home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-03-19 | 104.1 KB | 4,237 lines |
- head 1.20;
- branch ;
- access ;
- symbols sprited:1.20.1;
- locks ; strict;
- comment @ * @;
-
-
- 1.20
- date 92.03.18.16.33.08; author rab; state Exp;
- branches 1.20.1.1;
- next 1.19;
-
- 1.19
- date 90.09.11.14.17.06; author kupfer; state Exp;
- branches ;
- next 1.18;
-
- 1.18
- date 90.09.05.18.56.18; author rab; state Exp;
- branches ;
- next 1.17;
-
- 1.17
- date 90.06.27.11.16.52; author shirriff; state Exp;
- branches ;
- next 1.16;
-
- 1.16
- date 90.02.28.11.10.06; author brent; state Exp;
- branches ;
- next 1.15;
-
- 1.15
- date 90.02.08.13.42.09; author ouster; state Exp;
- branches ;
- next 1.14;
-
- 1.14
- date 89.07.28.16.04.40; author ouster; state Exp;
- branches ;
- next 1.13;
-
- 1.13
- date 89.07.19.08.58.37; author ouster; state Exp;
- branches ;
- next 1.12;
-
- 1.12
- date 89.06.03.16.46.20; author ouster; state Exp;
- branches ;
- next 1.11;
-
- 1.11
- date 89.04.20.10.24.35; author ouster; state Exp;
- branches ;
- next 1.10;
-
- 1.10
- date 89.04.19.15.26.54; author ouster; state Exp;
- branches ;
- next 1.9;
-
- 1.9
- date 89.03.11.12.32.01; author ouster; state Exp;
- branches ;
- next 1.8;
-
- 1.8
- date 89.01.19.12.36.13; author ouster; state Exp;
- branches ;
- next 1.7;
-
- 1.7
- date 89.01.16.10.39.54; author ouster; state Exp;
- branches ;
- next 1.6;
-
- 1.6
- date 88.10.14.13.09.19; author brent; state Exp;
- branches ;
- next 1.5;
-
- 1.5
- date 88.10.07.19.00.59; author douglis; state Exp;
- branches ;
- next 1.4;
-
- 1.4
- date 88.09.28.10.06.32; author brent; state Exp;
- branches ;
- next 1.3;
-
- 1.3
- date 88.07.28.17.47.40; author ouster; state Exp;
- branches ;
- next 1.2;
-
- 1.2
- date 88.07.25.13.27.45; author ouster; state Exp;
- branches ;
- next 1.1;
-
- 1.1
- date 88.07.01.09.40.52; author ouster; state Exp;
- branches ;
- next ;
-
- 1.20.1.1
- date 92.03.18.16.34.23; author kupfer; state Exp;
- branches ;
- next ;
-
-
- desc
- @@
-
-
- 1.20
- log
- @Lint. (Mike checking in for Bob.)
- @
- text
- @/*
- * ttyDriver.c --
- *
- * The routines in this module implement an emulator for the
- * UNIX 4.2 BSD tty driver. The emulation is done in a way
- * that is independent of the specific environme (kernel, user,
- * etc.) by using a set of callback procedures to interface to
- * a raw device on one side and a client on the "cooked" side..
- *
- * Copyright 1987, 1989 Regents of the University of California
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyDriver.c,v 1.19 90/09/11 14:17:06 kupfer Exp Locker: rab $ SPRITE (Berkeley)";
- #endif not lint
-
- #include <sprite.h>
- #include <dev/tty.h>
- #include <fs.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <errno.h>
- #include <signal.h>
- #include <stdlib.h>
- #include <sys/ioctl.h>
- #include <fmt.h>
- #include "td.h"
-
- /*
- * The structure below corresponds to one terminal (one call to Td_Create).
- */
-
- typedef struct Terminal {
- /*
- * Controlling parameters for terminal. These all have exactly the
- * same meanings as in 4.3 BSD; see the 4.3 BSD terminal driver
- * documentation for details.
- */
-
- struct sgttyb sgttyb;
- struct tchars tchars;
- struct ltchars ltchars;
- int localMode;
- struct winsize winsize;
-
- /*
- * State of the terminal.
- */
-
- int column; /* Column where the next character will be
- * echoed (i.e., cursor position). Needed
- * in order to handle tabs correctly. */
- int owner; /* Identifier of controlling process or process
- * group (signals are sent here). */
- int numOpens; /* Number of opens that have been completed
- * successfully but not yet closed. */
- int flags; /* See below for definitions. */
-
- /*
- * Input buffer, indexed circularly. The buffer is reallocated
- * with a larger size if it ever fills up.
- */
-
- char *inputBuffer; /* Input buffer area (malloc'ed). */
- int inBufSize; /* Number of bytes in inputBuffer. */
- int lastAddedIn; /* Index of last character added to buffer. */
- int lastRemovedIn; /* Index of last place from which character
- * was removed from buffer. If lastAddedIn =
- * lastRemovedIn, the buffer is empty. */
- int lastBreak; /* Index of last break character (newline,
- * etc.) or lastRemovedIn if none in buffer. */
- int lastHidden; /* Value of lastAddedIn at the time the last
- * output to the terminal was done. Characters
- * before this can't be smoothly backspaced
- * over, because there's output in front of
- * them on the screen. -1 means there are no
- * editable characters in the buffer that are
- * hidden. */
-
- /*
- * In order to backspace correctly over weird things like tabs, the
- * following two variables keep track of an index position in the input
- * buffer, and the column just to the right of where that character was
- * echoed on the display. KeyIndex is either the same as lastBreak or
- * lastHidden or lastRemovedIn, and has two properties: a) it will
- * never be backspaced over in CRT mode; and b) no characters beyond
- * this one will be returned to the application until keyIndex is first
- * advanced.
- */
-
- int keyIndex;
- int keyColumn; /* Column just after keyIndex character. */
-
- /*
- * Output buffer, indexed circularly. This buffer also grows
- * dynamically if necessary (this is necessary so that new room can
- * be made for characters being echoed, even if the buffer was
- * previously "full"). However, the cooked side of the terminal
- * is marked "not ready for output" whenever there are more than
- * cookedOutputLimit characters in the buffer (but any call to
- * Td_PutCooked will always complete; it is up to the cooked-side
- * callbacks to stop calling Td_PutCooked). The goal here is to
- * keep the application from getting too many characters ahead of
- * the actual device.
- */
-
- char *outputBuffer; /* Output buffer area (malloc'ed). */
- int outBufSize; /* Number of bytes in outputBuffer. */
- int lastAddedOut; /* Index of last character added to
- * outputBuffer. */
- int lastRemovedOut; /* Index of last character removed from
- * outputBufer. */
- int outCharsBuffered; /* Number of characters bufferred in
- * outputBuffer. */
- int cookedOutputLimit; /* Mark cooked side not ready for output
- * whenever outCharsBuffered is greater
- * than this. */
-
- /*
- * Callback procedures and data provided by the client:
- */
-
- int (*cookedProc)_ARGS_((ClientData, int operation, int inBufSize,
- char *inBuffer, int outBufSize,
- char *outBuffer));
- /* Procedure to call to register change
- * in state of cooked-side interface. */
- ClientData cookedData; /* Value to pass to cookedProc. */
- int (*rawProc)_ARGS_((ClientData, int operation, int inBufSize,
- char *inBuffer, int outBufSize,
- char *outBuffer));
- /* Procedure to call to register change
- * in state of raw-side interface. */
- ClientData rawData; /* Value to pass to rawProc. */
- } Terminal;
-
- /* Flag values:
- *
- * EXCLUSIVE: No more opens should be allowed until terminal
- * has been completely closed.
- * BS_IN_PROGRESS: A printing backspace sequence (delimited by
- * "\" and "/") is in progress, and will eventually
- * need the closing "/".
- * LITERAL_NEXT: The next character should be taken literally,
- * and should be put into the input buffer with
- * no special interpretation.
- * OWNER_FAMILY: 1 means the owner is a process family. 0 means
- * it's a single process.
- * OUTPUT_OFF: 1 means output to the raw device has been stopped,
- * for example because ^S was typed.
- */
-
- #define EXCLUSIVE 0x1
- #define BS_IN_PROGRESS 0x2
- #define LITERAL_NEXT 0x4
- #define OWNER_FAMILY 0x8
- #define OUTPUT_OFF 0x10
-
- /*
- * Default values for tty parameters:
- */
-
- struct sgttyb sgttybDefault = {
- B9600, B9600, 010, 025, EVENP|ODDP|CRMOD|ECHO
- };
- struct tchars tcharsDefault = {
- 03, 034, 021, 023, 04, -1
- };
- struct ltchars ltcharsDefault = {
- 032, 031, 022, 017, 027, 026
- };
- int localModeDefault = LCRTBS|LCRTERA|LCRTKIL|LCTLECH;
- struct winsize winsizeDefault = {
- 0, 0, 0, 0
- };
-
- /*
- * Macros for moving buffer pointers forward and backward circularly.
- */
-
- #define NEXT(src, size, dst) \
- (dst) = (src)+1; \
- if ((dst) >= (size)) { \
- (dst) = 0; \
- }
-
- #define PREV(src, size, dst) \
- (dst) = (src)-1; \
- if ((dst) < 0) { \
- (dst) = (size)-1; \
- }
-
- int td_Debug = 0;
-
- /*
- * Forward declarations for procedures defined later in this file:
- */
-
- static void TdBackspace _ARGS_((Terminal *tPtr));
- static void TdEcho _ARGS_((Terminal *tPtr, int c));
- static void TdFlushInput _ARGS_((Terminal *tPtr));
- static void TdFlushOutput _ARGS_((Terminal *tPtr));
- static void TdPutChar _ARGS_((Terminal *tPtr, int c));
- static void TdRetypeInput _ARGS_((Terminal *tPtr, int start));
- static int FormatInput _ARGS_((int command, Fmt_Format format,
- int inputSize, Address input,
- int *newInputSizePtr, Address newInput));
- static int FormatOutput _ARGS_((int command, Fmt_Format format,
- int outputSize, Address output,
- int *newOutputSizePtr,
- Address newOutput));
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Td_Create --
- *
- * This procedure creates and initializes a new terminal
- * driver.
- *
- * Results:
- * The return value is a handle that is used to refer to the
- * driver when calling other Td_ procedures, such as Td_Delete.
- *
- * Side effects:
- * The procedures cookedProc and rawProc may be invoked by
- * other procedures in this module at later times. See the
- * man page for details.
- *
- *----------------------------------------------------------------------
- */
-
- Td_Terminal
- Td_Create(bufferSize, cookedProc, cookedData, rawProc, rawData)
- int bufferSize; /* How much buffer space to allow on
- * output. */
- int (*cookedProc)_ARGS_((ClientData, int operation, int inBufSize,
- char *inBuffer, int outBufSize,
- char *outBuffer));
- /* Procedure to call for control operations
- * on cooked side of driver. */
- ClientData cookedData; /* Arbitrary value, provided by caller,
- * which will be passed to cookedProc
- * whenever it is invoked. */
- int (*rawProc)_ARGS_((ClientData, int operation, int inBufSize,
- char *inBuffer, int outBufSize,
- char *outBuffer));
- /* Procedure to call for control operations
- * on raw side of driver. */
- ClientData rawData; /* Arbitrary value, provided by caller,
- * which will be passed to rawProc whenever
- * it is invoked. */
- {
- register Terminal *tPtr;
- Td_BaudRate baud;
-
- tPtr = (Terminal *) malloc(sizeof(Terminal));
- tPtr->sgttyb = sgttybDefault;
- tPtr->tchars = tcharsDefault;
- tPtr->ltchars = ltcharsDefault;
- tPtr->localMode = localModeDefault;
- tPtr->winsize = winsizeDefault;
- tPtr->column = 0;
- tPtr->owner = -1;
- tPtr->flags = 0;
- tPtr->inputBuffer = (char *) malloc(100);
- tPtr->inBufSize = 100;
- tPtr->lastAddedIn = 0;
- tPtr->lastRemovedIn = 0;
- tPtr->lastBreak = 0;
- tPtr->lastHidden = -1;
- tPtr->keyIndex = 0;
- tPtr->keyColumn = 0;
- tPtr->outputBuffer = (char *) malloc(1000);
- tPtr->outBufSize = 1000;
- tPtr->lastAddedOut = 0;
- tPtr->lastRemovedOut = 0;
- tPtr->outCharsBuffered = 0;
- tPtr->cookedOutputLimit = bufferSize;
- tPtr->cookedProc = cookedProc;
- tPtr->cookedData = cookedData;
- tPtr->rawProc = rawProc;
- tPtr->rawData = rawData;
-
- /*
- * Fetch the actual baud rate from the raw device manager.
- */
-
- if ((*rawProc)(rawData, TD_RAW_GET_BAUD_RATE, 0, (char *) NULL,
- sizeof(baud), (char *) &baud) == sizeof(baud)) {
- tPtr->sgttyb.sg_ispeed = baud.ispeed;
- tPtr->sgttyb.sg_ospeed = baud.ospeed;
- }
-
- return (Td_Terminal) tPtr;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Td_Delete --
- *
- * Close down a terminal driver, destroying all of the state
- * associated with it.
- *
- * Results:
- * None.
- *
- * Side effects:
- * A hangup is simulated on the cooked side of the driver, and
- * memory is released. The caller should never again use
- * terminal.
- *
- *----------------------------------------------------------------------
- */
-
- void
- Td_Delete(terminal)
- Td_Terminal terminal; /* Token identifying terminal (returned
- * by previous call to Td_Create). */
- {
- register Terminal *tPtr = (Terminal *) terminal;
-
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_SHUTDOWN, 0, (char *) NULL,
- 0, (char *) NULL);
- free((char *) tPtr->inputBuffer);
- free((char *) tPtr->outputBuffer);
- free((char *) tPtr);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Td_Open --
- *
- * This procedure should be called before accepting a new
- * "open" for a terminal. It indicates whether new opens
- * are permitted.
- *
- * Results:
- * The return value is zero if the open is to be permitted,
- * and a non-zero errno value if it is to be denied. If the
- * open is successful, *selectBitsPtr is filled in with the
- * initial select state for the terminal.
- *
- * Side effects:
- * Information counting open streams on the terminal gets
- * updated.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Td_Open(terminal, selectBitsPtr)
- Td_Terminal terminal; /* Token for the terminal to be
- * checked. */
- int *selectBitsPtr; /* Put initial select state here. */
- {
- register Terminal *tPtr = (Terminal *) terminal;
-
- if (tPtr->flags & EXCLUSIVE) {
- return EBUSY;
- }
- tPtr->numOpens++;
- *selectBitsPtr = 0;
- if ((tPtr->lastBreak != tPtr->lastRemovedIn)
- || (tPtr->localMode & LPENDIN)) {
- *selectBitsPtr |= FS_READABLE;
- }
- if (tPtr->outCharsBuffered < tPtr->cookedOutputLimit) {
- *selectBitsPtr |= FS_WRITABLE;
- }
- return 0;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Td_Close --
- *
- * This procedure should be called whenever all of the I/O streams
- * associated with a single open on a terminal have been closed.
- *
- * Results:
- * none.
- *
- * Side effects:
- * State in the terminal is updated to reflect the close.
- *
- *----------------------------------------------------------------------
- */
-
- void
- Td_Close(terminal)
- Td_Terminal terminal; /* Token for the terminal to be
- * checked. */
- {
- register Terminal *tPtr = (Terminal *) terminal;
-
- tPtr->numOpens--;
- if (tPtr->numOpens == 0) {
- tPtr->flags &= ~EXCLUSIVE;
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Td_GetCooked --
- *
- * Retrieve characters that are ready to be read from the cooked
- * side of a terminal driver.
- *
- * Results:
- * The return value is normally 0. If non-zero, it indicates
- * that an error occurred and holds a UNIX errno. Most often,
- * this is EWOULDBLOCK, meaning that no characters were
- * available. The value at numCharsPtr is overwritten with the
- * actual number of characters returned at buffer, and will be
- * 0 if an error or end-of-file occurred. *SigNumPtr is overwritten
- * with a signal to send to the invoking process, or 0. *SelectBitsPtr
- * is updated to reflect the readability of the terminal.
- *
- * Side effects:
- * Characters are removed from the terminal's input buffer.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Td_GetCooked(terminal, pID, familyID, numCharsPtr, buffer,
- sigNumPtr, selectBitsPtr)
- Td_Terminal terminal; /* Token identifying terminal. */
- int pID; /* Process invoking operation. */
- int familyID; /* Family of pID. */
- int *numCharsPtr; /* Points to maximum number of characters to
- * read from terminal. Overwritten by number
- * of chars. actually returned. */
- char *buffer; /* Where to place characters that are read. */
- int *sigNumPtr; /* Overwrite this with the number of a signal
- * to generate for the calling process. 0
- * means no signal. */
- int *selectBitsPtr; /* The FS_READABLE bit in this word gets
- * updated to reflect whether or not there
- * are still more readable characters after
- * the ones returned. */
- {
- register Terminal *tPtr = (Terminal *) terminal;
- register char *dest;
- int count, result;
-
- *sigNumPtr = 0;
-
- /*
- * See if this process owns the terminal. If not, then signal it
- * and don't give it any input.
- */
-
- if (!(tPtr->flags & OWNER_FAMILY)) {
- if ((pID != tPtr->owner) && (tPtr->owner != -1)) {
- notOwner:
- *sigNumPtr = SIGTTIN;
- *numCharsPtr = 0;
- result = EINTR;
- goto done;
- }
- } else if ((familyID != tPtr->owner) && (tPtr->owner != -1)) {
- goto notOwner;
- }
-
- /*
- * Re-echo buffered characters, if so requested.
- */
-
- if (tPtr->localMode & LPENDIN) {
- int oldCharsBuffered;
-
- oldCharsBuffered = tPtr->outCharsBuffered;
- tPtr->localMode &= ~LPENDIN;
- TdRetypeInput(tPtr, tPtr->lastRemovedIn);
- if ((oldCharsBuffered == 0) && (tPtr->outCharsBuffered != 0) &&
- !(tPtr->flags & OUTPUT_OFF)) {
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_OUTPUT_READY,
- 0, (char *) NULL, 0, (char *) NULL);
- }
- }
-
- /*
- * Make sure there's information ready for the terminal. If not,
- * then block the process.
- */
-
- if (tPtr->lastBreak == tPtr->lastRemovedIn) {
- *numCharsPtr = 0;
- *selectBitsPtr &= ~FS_READABLE;
- return EWOULDBLOCK;
- }
-
- /*
- * Copy bytes from the input buffer to the caller's buffer,
- * and update the terminal's input buffer pointer.
- */
-
- count = 0;
- dest = buffer;
- while ((tPtr->lastRemovedIn != tPtr->lastBreak) &&
- (count < *numCharsPtr)) {
- register char c;
-
- NEXT(tPtr->lastRemovedIn, tPtr->inBufSize, tPtr->lastRemovedIn);
- count++;
- c = tPtr->inputBuffer[tPtr->lastRemovedIn];
- *dest = c;
- dest++;
- if (!(tPtr->sgttyb.sg_flags & (RAW|CBREAK))) {
- if (c == tPtr->tchars.t_eofc) {
- count--; /* Don't return end-of-file chars. */
- break;
- } else if ((c == '\n') || (c == tPtr->tchars.t_brkc)) {
- break;
- }
- }
- }
- *numCharsPtr = count;
- result = 0;
-
- done:
- if (tPtr->lastBreak == tPtr->lastRemovedIn) {
- *selectBitsPtr &= ~FS_READABLE;
- } else {
- *selectBitsPtr |= FS_READABLE;
- }
- return result;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Td_PutCooked --
- *
- * Add characters to the output buffer for a terminal.
- *
- * Results:
- * The return value is always 0 (the output is grown enough to
- * hold all the output characters). The value at *numBytesPtr
- * is left unchanged to indicate that all the characters were
- * accepted, *sigNumPtr is overwritten with a signal to send
- * to the invoking process (or 0), and *selectBitsPtr is updated
- * to reflect whether the terminal's output buffer is now full.
- *
- * Side effects:
- * Output processing is performed on the characters in buffer,
- * and they are queued for output on the terminal's raw side.
- *
- *----------------------------------------------------------------------
- */
-
- /* ARGSUSED */
- int
- Td_PutCooked(terminal, numBytesPtr, buffer, sigNumPtr, selectBitsPtr)
- Td_Terminal terminal; /* Token identifying terminal. */
- int *numBytesPtr; /* Points to maximum number of characters
- * to write to terminal. Not modified
- * by this procedure. */
- register char *buffer; /* Characters to write. */
- int *sigNumPtr; /* Overwrite this with the number of a signal
- * to generate for the calling process. 0
- * means no signal. */
- int *selectBitsPtr; /* The FS_WRITABLE bit in this word gets
- * updated to reflect whether or not there
- * are still more space available in the
- * terminal's output buffer. */
- {
- register Terminal *tPtr = (Terminal *) terminal;
- register char c;
- int i, oldCharsBuffered;
-
- *sigNumPtr = 0;
-
- oldCharsBuffered = tPtr->outCharsBuffered;
- for (i = 0; i < *numBytesPtr; i++, buffer++) {
- c = *buffer;
- if ((tPtr->sgttyb.sg_flags & RAW) || (tPtr->localMode & LLITOUT)) {
- TdPutChar(tPtr, c);
- continue;
- }
- c &= 0177;
- if (c == 04) { /* End of file (^D) ignored */
- continue;
- } else if ((c == '\n') && (tPtr->sgttyb.sg_flags & CRMOD)) {
- TdPutChar(tPtr, '\r');
- TdPutChar(tPtr, '\n');
- } else {
- TdPutChar(tPtr, c);
- }
- }
- tPtr->keyIndex = tPtr->lastAddedIn;
- tPtr->keyColumn = tPtr->column;
- if (tPtr->lastAddedIn != tPtr->lastRemovedIn) {
- tPtr->lastHidden = tPtr->lastAddedIn;
- }
- if ((oldCharsBuffered == 0) && (tPtr->outCharsBuffered != 0) &&
- !(tPtr->flags & OUTPUT_OFF)) {
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_OUTPUT_READY,
- 0, (char *) NULL, 0, (char *) NULL);
- }
- if (tPtr->outCharsBuffered >= tPtr->cookedOutputLimit) {
- *selectBitsPtr &= ~FS_WRITABLE;
- } else {
- *selectBitsPtr |= FS_WRITABLE;
- }
- return 0;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Td_ControlCooked --
- *
- * This procedure is used to invoke iocontrol operations on the
- * cooked side of a terminal driver.
- *
- * Results:
- * If the operation completed successfully then the return value
- * is zero. If the operation failed, then the return value is a
- * UNIX errno indicating what went wrong. *SigNumPtr gets
- * overwritten with the number of a signal to send to the invoking
- * process (or 0), and *selectBitsPtr gets filled in with information
- * about whether or not the terminal is now readable or writable.
- *
- * Side effects:
- * Depends on the iocontrol; see the tty(4) man page for details.
- *
- *----------------------------------------------------------------------
- */
-
- /* ARGSUSED */
- int
- Td_ControlCooked(terminal, command, format, inputSize, input, outputSizePtr,
- output, sigNumPtr, selectBitsPtr)
- Td_Terminal terminal; /* Token for terminal. */
- int command; /* Iocontrol operation to perform
- * ( e.g. TIOCGETP). */
- Fmt_Format format; /* Byte-order/alignment format */
- int inputSize; /* Size of input, in bytes. */
- char *input; /* Input buffer: contains information
- * provided by client as input to
- * operation. */
- int *outputSizePtr; /* Largest amount of output that
- * client is prepared to receive. This
- * value is overwritten with the count
- * of actual bytes returned. */
- char *output; /* Place to store output bytes;
- * provided by caller. */
- int *sigNumPtr; /* Overwrite this with the number of
- * a signal to generate for the
- * calling process. 0 means no
- * signal. */
- int *selectBitsPtr; /* Store new select state of terminal
- * here. */
- {
- register Terminal *tPtr = (Terminal *) terminal;
- int count, result;
- char *out = (char *) NIL;
- int i;
- Ioc_Owner owner;
- int oldIspeed, oldOspeed, oldFlags, oldStopc, oldStartc;
-
- /*
- * The union below describes all of the possible formats in which
- * the input area may appear.
- */
-
- typedef union {
- int i;
- char chars[20];
- struct sgttyb sgttyb;
- struct tchars tchars;
- struct ltchars ltchars;
- Ioc_Owner owner;
- struct winsize winsize;
- } InBuf;
- InBuf newInputBuf;
- register InBuf *in = (InBuf *) input;
-
- if (td_Debug) {
- printf("Td_ControlCooked: command %d\n", command);
- }
-
- if (format != FMT_MY_FORMAT) {
- /*
- * Fix up the formatting of the input buffer.
- */
- int newSize = sizeof(newInputBuf);
- if (FormatInput(command, format, inputSize, input,
- &newSize, (Address) &newInputBuf) != FMT_OK) {
- goto invalid;
- }
- in = &newInputBuf;
- inputSize = newSize;
- }
- /*
- * Save certain pieces of information about the terminal so that
- * if they change we can call the raw control procedure.
- */
-
- oldIspeed = tPtr->sgttyb.sg_ispeed;
- oldOspeed = tPtr->sgttyb.sg_ospeed;
- oldFlags = tPtr->sgttyb.sg_flags;
- oldStopc = tPtr->tchars.t_stopc;
- oldStartc = tPtr->tchars.t_startc;
-
- *sigNumPtr = 0;
- count = 0;
- switch (command) {
-
- case IOC_TTY_SET_DISCIPLINE:
- if ((inputSize != sizeof(int))
- || (in->i != NTTYDISC)) {
- goto invalid;
- }
- break;
-
- case IOC_TTY_GET_DISCIPLINE:
- if (inputSize != 0) {
- goto invalid;
- }
- i = NTTYDISC;
- out = (char *) &i;
- count = sizeof(int);
- break;
-
- case IOC_TTY_GETP:
- if (inputSize != 0) {
- goto invalid;
- }
- out = (char *) &tPtr->sgttyb;
- count = sizeof(struct sgttyb);
- break;
-
- case IOC_TTY_SETP:
- /*
- * Technically, this code should delay until all characters
- * currently buffered for output have been printed, but
- * there's no easy way to do that here: ioctls must complete
- * immediately.
- */
- TdFlushInput(tPtr);
- case IOC_TTY_SETN:
- if (inputSize != sizeof(struct sgttyb)) {
- goto invalid;
- }
- if ((tPtr->sgttyb.sg_flags ^ in->sgttyb.sg_flags) & RAW) {
- /*
- * Going into or out of raw mode; always flush input
- * buffer.
- */
-
- TdFlushInput(tPtr);
- }
- tPtr->sgttyb = in->sgttyb;
- break;
-
- case IOC_TTY_EXCL:
- if (inputSize != 0) {
- goto invalid;
- }
- tPtr->flags |= EXCLUSIVE;
- break;
-
- case IOC_TTY_NXCL:
- if (inputSize != 0) {
- goto invalid;
- }
- tPtr->flags &= ~EXCLUSIVE;
- break;
-
- case IOC_TTY_HUP_ON_CLOSE: /* Not implemented. */
- goto invalid;
-
- case IOC_TTY_FLUSH: {
- /*
- * For compatibility with TIOCFLUSH, we accept one
- * integer argument which has the FREAD and FWRITE bits in it.
- */
- int flags;
- if (inputSize == 0) {
- flags = 0;
- } else {
- flags = in->i;
- }
- #ifndef FREAD
- #define FREAD 0x1
- #define FWRITE 0x2
- #endif
- if (flags == 0) {
- flags = FREAD|FWRITE;
- }
- if (flags & FREAD) {
- TdFlushInput(tPtr);
- }
- if (flags & FWRITE) {
- TdFlushOutput(tPtr);
- }
- break;
- }
- case IOC_TTY_INSERT_CHAR:
- if (inputSize != 1) {
- goto invalid;
- }
- Td_PutRaw((Td_Terminal) tPtr, 1, &in->chars[0]);
- break;
-
- case IOC_TTY_SET_BREAK:
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_START_BREAK,
- 0, (char *) NULL, 0, (char *) NULL);
- break;
-
- case IOC_TTY_CLEAR_BREAK:
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_START_BREAK,
- 0, (char *) NULL, 0, (char *) NULL);
- break;
-
- case IOC_TTY_SET_DTR:
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_SET_DTR,
- 0, (char *) NULL, 0, (char *) NULL);
- break;
-
- case IOC_TTY_CLEAR_DTR:
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_CLEAR_DTR,
- 0, (char *) NULL, 0, (char *) NULL);
- break;
-
- case IOC_GET_OWNER:
- if (inputSize != 0) {
- goto invalid;
- }
- owner.id = tPtr->owner;
- if (tPtr->flags & OWNER_FAMILY) {
- owner.procOrFamily = IOC_OWNER_FAMILY;
- } else {
- owner.procOrFamily = IOC_OWNER_PROC;
- }
- out = (char *) &owner;
- count = sizeof(owner);
- break;
-
- case IOC_SET_OWNER:
- if (inputSize != sizeof(Ioc_Owner)) {
- goto invalid;
- }
- tPtr->owner = in->owner.id;
- if (in->owner.procOrFamily == IOC_OWNER_FAMILY) {
- tPtr->flags |= OWNER_FAMILY;
- } else {
- tPtr->flags &= ~OWNER_FAMILY;
- }
- break;
-
- case IOC_NUM_READABLE:
- i = tPtr->lastBreak - tPtr->lastRemovedIn;
- if (i < 0) {
- i += tPtr->inBufSize;
- }
- out = (char *) &i;
- count = sizeof(int);
- break;
-
- case IOC_TTY_GET_TCHARS:
- if (inputSize != 0) {
- goto invalid;
- }
- out = (char *) &tPtr->tchars;
- count = sizeof(struct tchars);
- break;
-
- case IOC_TTY_SET_TCHARS:
- if (inputSize != sizeof(struct tchars)) {
- goto invalid;
- }
- tPtr->tchars = in->tchars;
- break;
-
- case IOC_TTY_BIS_LM:
- if (inputSize != sizeof(int)) {
- goto invalid;
- }
- tPtr->localMode |= in->i;
- break;
-
- case IOC_TTY_BIC_LM:
- if (inputSize != sizeof(int)) {
- goto invalid;
- }
- tPtr->localMode &= ~in->i;
- break;
-
- case IOC_TTY_SET_LM:
- if (inputSize != sizeof(int)) {
- goto invalid;
- }
- tPtr->localMode = in->i;
- break;
-
- case IOC_TTY_GET_LM:
- if (inputSize != 0) {
- goto invalid;
- }
- out = (char *) &tPtr->localMode;
- count = sizeof(int);
- break;
-
- case IOC_TTY_SET_LTCHARS:
- if (inputSize != sizeof(struct ltchars)) {
- goto invalid;
- }
- tPtr->ltchars = in->ltchars;
- break;
-
- case IOC_TTY_GET_LTCHARS:
- if (inputSize != 0) {
- goto invalid;
- }
- out = (char *) &tPtr->ltchars;
- count = sizeof(struct ltchars);
- break;
-
- case IOC_GET_FLAGS:
- i = 0;
- out = (char *) &i;
- count = sizeof(int);
- break;
- case IOC_SET_FLAGS:
- case IOC_SET_BITS:
- case IOC_CLEAR_BITS:
- case IOC_TTY_NOT_CONTROL_TTY:
- break;
-
- case IOC_TTY_GET_WINDOW_SIZE:
- if (inputSize != 0) {
- goto invalid;
- }
- out = (char *) &tPtr->winsize;
- count = sizeof(struct winsize);
- break;
-
- case IOC_TTY_SET_WINDOW_SIZE: {
- Td_Signal signalInfo;
- if (inputSize != sizeof(struct winsize)) {
- goto invalid;
- }
- tPtr->winsize = in->winsize;
- signalInfo.sigNum = SIGWINCH;
- signalInfo.groupID = tPtr->owner;
- (*tPtr->cookedProc)(tPtr->cookedData, TD_COOKED_SIGNAL,
- sizeof(signalInfo), (char *) &signalInfo,
- 0, (char *) NULL);
- break;
- }
-
- default:
- goto invalid;
- }
- /*
- * Fix up output buffer for the client. At this point
- * count = size of output data
- * out = pointer to output data
- * Here we rely on the Fmt_ library doing essentially a bcopy
- * if our format and the client's format are the same.
- */
- if (count != 0) {
- result = FormatOutput(command, format, count, out,
- outputSizePtr, output);
- if (result != FMT_OK) {
- result = EINVAL;
- if (td_Debug) {
- printf("Td_ControlCooked: command %d invalid output\n", command);
- }
- }
- } else {
- *outputSizePtr = 0;
- result = 0;
- }
-
- /*
- * Call the raw control procedure if anything changed that it needs
- * to know about.
- */
-
- if ((oldIspeed != tPtr->sgttyb.sg_ispeed)
- || (oldOspeed != tPtr->sgttyb.sg_ospeed)) {
- Td_BaudRate baud, baud2;
-
- baud.ispeed = tPtr->sgttyb.sg_ispeed;
- baud.ospeed = tPtr->sgttyb.sg_ospeed;
- if ((*tPtr->rawProc)(tPtr->rawData, TD_RAW_SET_BAUD_RATE,
- sizeof(baud), (char *) &baud,
- sizeof(baud2), (char *) &baud2) == sizeof(baud2)) {
-
- /*
- * Device has overridden the baud-rate change; take its advice.
- */
-
- tPtr->sgttyb.sg_ispeed = baud2.ispeed;
- tPtr->sgttyb.sg_ospeed = baud2.ospeed;
- }
- }
- if (((oldFlags & RAW) != (tPtr->sgttyb.sg_flags & RAW))
- || (oldStopc != tPtr->tchars.t_stopc)
- || (oldStartc != tPtr->tchars.t_startc)) {
- Td_FlowChars flow;
-
- if (tPtr->sgttyb.sg_flags & RAW) {
- flow.stop = flow.start = -1;
- } else {
- flow.stop = tPtr->tchars.t_stopc;
- flow.start = tPtr->tchars.t_startc;
- }
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_FLOW_CHARS,
- sizeof(flow), (char *) &flow, 0, (char *) NULL);
- }
-
- /*
- * Setting the select bits is a bit tricky: if LPENDIN is set, then
- * we need to find out when the next read is done. So, make the device
- * appear to be readable even if it isn't. Otherwise, we won't be told
- * when the device is read.
- */
-
- done:
- *selectBitsPtr = 0;
- if ((tPtr->lastBreak != tPtr->lastRemovedIn)
- || (tPtr->localMode & LPENDIN)) {
- *selectBitsPtr |= FS_READABLE;
- }
- if (tPtr->outCharsBuffered < tPtr->cookedOutputLimit) {
- *selectBitsPtr |= FS_WRITABLE;
- }
- return result;
-
- invalid:
- if (td_Debug) {
- printf("Td_ControlCooked: command %d invalid input\n", command);
- }
- *outputSizePtr = 0;
- result = EINVAL;
- goto done;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * FormatInput --
- *
- * Re-format the input buffer of an I/O control. This is required
- * if the client is on a host with a different byte order/alignment.
- * This uses the Fmt_Convert library routine.
- *
- * Results:
- * This returns zero if all goes well.
- * Otherwise a FMT_ error code is returned.
- *
- * Side effects:
- * The reformatted input is put into newBuffer. The true size of
- * the data in this buffer is returned in *newInputSizePtr.
- *
- *----------------------------------------------------------------------
- */
-
- static int
- FormatInput(command, format, inputSize, input, newInputSizePtr, newInput)
- int command; /* I/O Control command */
- Fmt_Format format; /* Format of client host */
- int inputSize; /* Size of input buffer */
- Address input; /* Input buffer in client format */
- int *newInputSizePtr; /* In/Out - Size of new input buffer */
- Address newInput; /* Out - Input buffer in our format */
- {
- int status = FMT_OK;
- char *fmtString = "";
-
- switch (command) {
-
- case IOC_TTY_GET_DISCIPLINE:
- case IOC_TTY_GETP:
- case IOC_TTY_EXCL:
- case IOC_TTY_NXCL:
- case IOC_GET_OWNER:
- case IOC_TTY_GET_TCHARS:
- case IOC_TTY_GET_LM:
- case IOC_TTY_GET_LTCHARS:
- case IOC_TTY_GET_WINDOW_SIZE:
- case IOC_TTY_NOT_CONTROL_TTY:
- default:
- *newInputSizePtr = 0;
- goto noconversion;
-
- case IOC_TTY_FLUSH:
- /*
- * Optional int
- */
- if (inputSize == 0) {
- *newInputSizePtr = 0;
- goto noconversion;
- } else {
- fmtString = "w";
- }
- break;
-
- case IOC_TTY_SET_DISCIPLINE:
- case IOC_TTY_BIS_LM:
- case IOC_TTY_BIC_LM:
- case IOC_TTY_SET_LM:
- /*
- * One int
- */
- fmtString = "w";
- break;
-
- case IOC_TTY_SETP:
- case IOC_TTY_SETN:
- /*
- * struct sgttyb
- */
- fmtString = "{b4h}";
- break;
-
- case IOC_TTY_INSERT_CHAR:
- /*
- * One char
- */
- fmtString = "b";
- break;
-
- case IOC_SET_OWNER:
- /*
- * Ioc_Owner
- */
- fmtString = "{w2}";
- break;
-
- case IOC_TTY_SET_TCHARS:
- /*
- * struct tchars
- */
- fmtString = "{b6}";
- break;
-
- case IOC_TTY_SET_LTCHARS:
- /*
- * struct ltchars
- */
- fmtString = "{b6}";
- break;
-
-
- case IOC_TTY_SET_WINDOW_SIZE: {
- /*
- * struct winsize
- */
- fmtString = "{h4}";
- break;
- }
-
- }
- status = Fmt_Convert(fmtString, format, &inputSize, input, FMT_MY_FORMAT,
- newInputSizePtr, newInput);
- noconversion:
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * FormatOutput --
- *
- * Re-format the output buffer of an I/O control.
- * This uses the Fmt_Convert library routine.
- *
- * Results:
- * This returns zero if all goes well.
- * Otherwise a FMT_ error code is returned.
- *
- * Side effects:
- * The reformatted output is put into newOutput. The true size of
- * the data in this buffer is returned in *newOutputSizePtr.
- *
- *----------------------------------------------------------------------
- */
-
- static int
- FormatOutput(command, format, outputSize, output, newOutputSizePtr, newOutput)
- int command; /* I/O Control command */
- Fmt_Format format; /* Format of client host */
- int outputSize; /* Size of input buffer (in our format) */
- Address output; /* Output buffer in our format */
- int *newOutputSizePtr; /* In/Out - Size of new output buffer */
- Address newOutput; /* Out - Output buffer in the client's format */
- {
- int status = FMT_OK;
- char *fmtString = "";
-
- switch (command) {
-
- case IOC_TTY_SET_DISCIPLINE:
- case IOC_TTY_SETP:
- case IOC_TTY_SETN:
- case IOC_TTY_EXCL:
- case IOC_TTY_NXCL:
- case IOC_TTY_FLUSH:
- case IOC_TTY_INSERT_CHAR:
- case IOC_SET_OWNER:
- case IOC_TTY_SET_TCHARS:
- case IOC_TTY_BIS_LM:
- case IOC_TTY_BIC_LM:
- case IOC_TTY_SET_LM:
- case IOC_TTY_SET_LTCHARS:
- case IOC_TTY_NOT_CONTROL_TTY:
- default:
- *newOutputSizePtr = 0;
- goto noconversion;
-
- case IOC_TTY_GET_DISCIPLINE:
- case IOC_NUM_READABLE:
- case IOC_TTY_GET_LM:
- case IOC_GET_FLAGS:
- /*
- * One int
- */
- fmtString = "w";
- break;
-
- case IOC_TTY_GETP:
- /*
- * struct sgttyb
- */
- fmtString = "{b4h}";
- break;
-
- case IOC_GET_OWNER:
- /*
- * Ioc_Owner
- */
- fmtString = "{w2}";
- break;
-
- case IOC_TTY_GET_TCHARS:
- /*
- * struct tchars
- */
- fmtString = "{b6}";
- break;
-
- case IOC_TTY_GET_LTCHARS:
- /*
- * struct ltchars
- */
- fmtString = "{b6}";
- break;
-
- case IOC_TTY_GET_WINDOW_SIZE:
- /*
- * struct winsize
- */
- fmtString = "{h4}";
- break;
- }
- status = Fmt_Convert(fmtString, FMT_MY_FORMAT, &outputSize, output, format,
- newOutputSizePtr, newOutput);
- noconversion:
- return(status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Td_GetRaw --
- *
- * Retrieve characters that are ready to be output from the
- * terminal driver to the raw device.
- *
- * Results:
- * The return value is a count of the number of characters
- * actually returned at buffer. This will be less than or
- * equal to numChars. A return value of 0 indicates that
- * there are no characters in terminal's output buffer or
- * that output has been disabled.
- *
- * Side effects:
- * Characters are removed from the terminal's output buffer,
- * and the cooked side may be notified that the terminal is
- * writable again.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Td_GetRaw(terminal, numChars, buffer)
- Td_Terminal terminal; /* Token identifying terminal. */
- int numChars; /* Maximum number of characters to read
- * from terminal's output buffer. */
- register char *buffer; /* Where to place characters that are read. */
- {
- register Terminal *tPtr = (Terminal *) terminal;
- int count;
-
- if (tPtr->flags & OUTPUT_OFF) {
- return 0;
- }
- for (count = 0; count < numChars; count++, buffer++) {
- if (tPtr->lastRemovedOut == tPtr->lastAddedOut) {
- break;
- }
- NEXT(tPtr->lastRemovedOut, tPtr->outBufSize, tPtr->lastRemovedOut);
- *buffer = tPtr->outputBuffer[tPtr->lastRemovedOut];
- }
- tPtr->outCharsBuffered -= count;
- if (tPtr->outCharsBuffered < tPtr->cookedOutputLimit) {
- (*tPtr->cookedProc)(tPtr->cookedData, TD_COOKED_WRITES_OK,
- 0, (char *) NULL, 0, (char *) NULL);
- }
- return count;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Td_PutRaw --
- *
- * This procedure is invoked when characters arrive from the
- * raw device associated with the terminal (e.g., from the
- * keyboard). It adds them to the input buffer of the terminal
- * and does appropriate line editing etc.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Characters are added to the input buffer, and may be made
- * available on the cooked side of the terminal. Echoed
- * characters get added to the output buffer, which could result
- * in a call to the raw control procedure.
- *
- *----------------------------------------------------------------------
- */
-
- void
- Td_PutRaw(terminal, numChars, buffer)
- Td_Terminal terminal; /* Token identifying terminal. */
- int numChars; /* Number of characters to process. */
- char *buffer; /* Characters that were ostensibly typed
- * on the raw device's keyboard. */
- {
- register Terminal *tPtr = (Terminal *) terminal;
- int next, oldCharsBuffered;
- register char c = '\0'; /* dummy initial value */
- Td_Signal signalInfo;
-
- oldCharsBuffered = tPtr->outCharsBuffered;
- tPtr->localMode &= ~LFLUSHO;
-
- /*
- * According to the 4.3 BSD manual page, we should re-echo everything
- * in the input buffer if LPENDIN is set here. But this appears to
- * produce the wrong results and I suspect that it isn't even
- * implemented in BSD. So it's not implemented here either.
- */
-
- for ( ; numChars > 0; numChars--, buffer++) {
- c = *buffer;
-
- /*
- * Skip all further processing if in raw mode.
- */
-
- if (tPtr->sgttyb.sg_flags & RAW) {
- goto addToBuffer;
- }
- c &= 0x7f;
-
- /*
- * Handle flow-control characters.
- */
-
-
- if (c == tPtr->tchars.t_stopc) {
- if (tPtr->flags & OUTPUT_OFF) {
- if (c == tPtr->tchars.t_startc) {
- goto restartOutput;
- }
- } else {
- tPtr->flags |= OUTPUT_OFF;
- }
- continue;
- } else if (c == tPtr->tchars.t_startc) {
- restartOutput:
- tPtr->flags &= ~OUTPUT_OFF;
- if (tPtr->outCharsBuffered != 0) {
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_OUTPUT_READY,
- 0, (char *) NULL, 0, (char *) NULL);
- }
- continue;
- } else if ((tPtr->flags & OUTPUT_OFF) && !(tPtr->localMode & LDECCTQ)) {
- tPtr->flags &= ~OUTPUT_OFF;
- if (tPtr->outCharsBuffered != 0) {
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_OUTPUT_READY,
- 0, (char *) NULL, 0, (char *) NULL);
- }
- }
-
- /*
- * If the last character typed was a "quote" character, then
- * just add the new character to the input buffer without
- * additional processing.
- */
-
- if (tPtr->flags & LITERAL_NEXT) {
- tPtr->flags &= ~LITERAL_NEXT;
- goto addToBuffer;
- }
-
- /*
- * Handle output-flushing character. Clearing oldCharsBuffered
- * is essential, otherwise, the raw client won't be notified if
- * characters are added to the output buffer in this procedure.
- */
-
- if (c == tPtr->ltchars.t_flushc) {
- if (tPtr->localMode & LFLUSHO) {
- tPtr->localMode &= ~LFLUSHO;
- } else {
- TdFlushOutput(tPtr);
- oldCharsBuffered = 0;
- TdEcho(tPtr, c);
- TdRetypeInput(tPtr, tPtr->lastRemovedIn);
- tPtr->localMode |= LFLUSHO;
- }
- continue;
- }
-
- /*
- * Handle line-editing characters such as erase and kill.
- */
-
- if ((c == '\r') && (tPtr->sgttyb.sg_flags & CRMOD)) {
- c = '\n';
- }
- if (!(tPtr->sgttyb.sg_flags & CBREAK)) {
- if (c == tPtr->sgttyb.sg_erase) { /* Backspace. */
- if (tPtr->lastAddedIn != tPtr->lastBreak) {
- TdBackspace(tPtr);
- }
- continue;
- } else if (c == tPtr->ltchars.t_werasc) { /* Delete word. */
- int gotNonSpace = 0;
-
- while (tPtr->lastAddedIn != tPtr->lastBreak) {
- if (isspace(tPtr->inputBuffer[tPtr->lastAddedIn])) {
- if (gotNonSpace) {
- break;
- }
- } else {
- gotNonSpace = 1;
- }
- TdBackspace(tPtr);
- }
- continue;
- } else if (c == tPtr->sgttyb.sg_kill) { /* Delete line. */
- if ((tPtr->lastHidden != -1) || !(tPtr->localMode & LCRTKIL)) {
- TdEcho(tPtr, c);
- TdEcho(tPtr, '\n');
- tPtr->lastAddedIn = tPtr->lastBreak;
- tPtr->lastHidden = -1;
- } else {
- while (tPtr->lastAddedIn != tPtr->lastBreak) {
- TdBackspace(tPtr);
- }
- }
- continue;
- } else if (c == tPtr->ltchars.t_rprntc) { /* Re-echo all. */
- TdEcho(tPtr, c);
- TdEcho(tPtr, '\n');
- TdRetypeInput(tPtr, tPtr->lastRemovedIn);
- continue;
- }
- }
-
- if (c == tPtr->ltchars.t_lnextc) {
- tPtr->flags |= LITERAL_NEXT;
- continue;
- }
-
- /*
- * Generate signals in response to certain input characters. If this
- * isn't a signal character, then officially add it to the input
- * buffer.
- */
-
- if (c == tPtr->tchars.t_intrc) {
- signalInfo.sigNum = SIGINT;
- sendSignal:
- signalInfo.groupID = tPtr->owner;
- (*tPtr->cookedProc)(tPtr->cookedData, TD_COOKED_SIGNAL,
- sizeof(signalInfo), (char *) &signalInfo,
- 0, (char *) NULL);
- TdFlushInput(tPtr);
- TdFlushOutput(tPtr);
- oldCharsBuffered = 0;
- goto echo;
- } else if (c == tPtr->tchars.t_quitc) {
- signalInfo.sigNum = SIGQUIT;
- goto sendSignal;
- } else if (c == tPtr->ltchars.t_suspc) {
- signalInfo.sigNum = SIGTSTP;
- goto sendSignal;
- }
-
- /*
- * If the buffer is full, then reallocate it with a size twice as
- * large. Then add the character to the buffer.
- */
-
- addToBuffer:
- NEXT(tPtr->lastAddedIn, tPtr->inBufSize, next);
- if (next == tPtr->lastRemovedIn) {
- char *newBuffer;
- int src, dst;
-
- newBuffer = malloc((unsigned) 2*tPtr->inBufSize);
- for (src = tPtr->lastRemovedIn, dst = 0; src != tPtr->lastAddedIn; ) {
- NEXT(src, tPtr->inBufSize, src);
- dst += 1;
- newBuffer[dst] = tPtr->inputBuffer[src];
- }
- tPtr->lastBreak -= tPtr->lastRemovedIn;
- if (tPtr->lastBreak < 0) {
- tPtr->lastBreak += tPtr->inBufSize;
- }
- if (tPtr->lastHidden != -1) {
- tPtr->lastHidden -= tPtr->lastRemovedIn;
- if (tPtr->lastHidden < 0) {
- tPtr->lastHidden += tPtr->inBufSize;
- }
- }
- tPtr->inputBuffer = newBuffer;
- tPtr->inBufSize *= 2;
- tPtr->lastRemovedIn = 0;
- tPtr->lastAddedIn = dst;
- NEXT(dst, tPtr->inBufSize, next);
- }
- tPtr->inputBuffer[next] = c;
- tPtr->lastAddedIn = next;
-
- /*
- * Echo.
- */
-
- echo:
- if ((tPtr->sgttyb.sg_flags & ECHO) && !(tPtr->sgttyb.sg_flags & RAW)) {
- if (tPtr->flags & BS_IN_PROGRESS) {
- TdPutChar(tPtr, '/');
- tPtr->flags &= ~BS_IN_PROGRESS;
- }
- TdEcho(tPtr, c);
- }
- }
-
- /*
- * Are there any characters that are ready for reading? If so,
- * change the terminal's state to be readable and notify the
- * cooked side.
- */
-
- if ((tPtr->sgttyb.sg_flags & (RAW|CBREAK)) || (c == tPtr->tchars.t_eofc) ||
- (c == tPtr->tchars.t_brkc) || (c == '\n')) {
- tPtr->lastBreak = tPtr->lastAddedIn;
- tPtr->lastHidden = -1;
- tPtr->keyIndex = tPtr->lastAddedIn;
- tPtr->keyColumn = tPtr->column;
- (*tPtr->cookedProc)(tPtr->cookedData, TD_COOKED_READS_OK,
- 0, (char *) NULL, 0, (char *) NULL);
- }
-
- /*
- * If the output buffer just became non-empty, then notify the
- * raw control procedure.
- */
-
- if ((oldCharsBuffered == 0) && (tPtr->outCharsBuffered != 0) &&
- !(tPtr->flags & OUTPUT_OFF)) {
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_OUTPUT_READY,
- 0, (char *) NULL, 0, (char *) NULL);
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Td_ControlRaw --
- *
- * This procedure is used to tell the terminal driver that
- * certain special things happened on the raw side of the
- * terminal, such as a hangup or break.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Depends on the operation; see the man page for details
- * on what commands may be invoked.
- *
- *----------------------------------------------------------------------
- */
-
- /* ARGSUSED */
- void
- Td_ControlRaw(terminal, operation)
- Td_Terminal terminal; /* Token for terminal. */
- int operation; /* What just happened: TD_BREAK etc. */
- {
- register Terminal *tPtr = (Terminal *) terminal;
-
- switch (operation) {
- case TD_BREAK: {
-
- /*
- * Reset some of the terminal state, such as flow control,
- * then pretend an interrupt character was typed.
- */
-
- tPtr->flags &= ~(OUTPUT_OFF | BS_IN_PROGRESS | LITERAL_NEXT);
- if (tPtr->sgttyb.sg_flags & RAW) {
- char c = 0;
- Td_PutRaw(terminal, 1, &c);
- } else if ((int) tPtr->tchars.t_intrc != -1) {
- Td_PutRaw(terminal, 1, &tPtr->tchars.t_intrc);
- }
- if (tPtr->outCharsBuffered != 0) {
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_OUTPUT_READY,
- 0, (char *) NULL, 0, (char *) NULL);
- }
- break;
- }
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdPutChar --
- *
- * Add a character to the output buffer associated with a
- * terminal, and keep track of the current column while outputting
- * the character. This routine also substitutes spaces for tabs,
- * if that's the mode the terminal is in.
- *
- * Results:
- * None.
- *
- * Side effects:
- * TPtr->column gets updated and stuff gets added to the terminal's
- * output buffer. The output buffer will get grown if necessary.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- TdPutChar(tPtr, c)
- register Terminal *tPtr; /* Terminal on which to output. */
- char c; /* Character to output. */
- {
- /*
- * Ignore the character if output is being flushed.
- */
-
- if (tPtr->localMode & LFLUSHO) {
- return;
- }
-
- /*
- * Grow the output buffer if there isn't enough space for the
- * largest amount of information this procedure might want to
- * add to it.
- */
-
- if ((tPtr->outCharsBuffered + 8) >= tPtr->outBufSize) {
- char *newBuffer;
- int dst;
-
- newBuffer = malloc((unsigned) (2*tPtr->outBufSize));
- for (dst = 0; tPtr->lastRemovedOut != tPtr->lastAddedOut; ) {
- dst += 1;
- NEXT(tPtr->lastRemovedOut, tPtr->outBufSize, tPtr->lastRemovedOut);
- newBuffer[dst] = tPtr->outputBuffer[tPtr->lastRemovedOut];
- }
- tPtr->outputBuffer = newBuffer;
- tPtr->outBufSize *= 2;
- tPtr->lastRemovedOut = 0;
- tPtr->lastAddedOut = dst;
- }
-
- /*
- * Update column position, and add character(s) to the buffer.
- */
-
- if (isprint(c)) {
- tPtr->column += 1;
- } else if (c == '\r') {
- tPtr->column = 0;
- } else if (c == '\t') {
- int count = 8 - (tPtr->column & 07);
-
- tPtr->column += count;
- if ((tPtr->sgttyb.sg_flags & TBDELAY) == XTABS) {
- for ( ; count > 0; count--) {
- NEXT(tPtr->lastAddedOut, tPtr->outBufSize, tPtr->lastAddedOut);
- tPtr->outputBuffer[tPtr->lastAddedOut] = ' ';
- tPtr->outCharsBuffered++;
- }
- return;
- }
- } else if (c == '\b') {
- tPtr->column -= 1;
- }
- NEXT(tPtr->lastAddedOut, tPtr->outBufSize, tPtr->lastAddedOut);
- tPtr->outputBuffer[tPtr->lastAddedOut] = c;
- tPtr->outCharsBuffered++;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdEcho --
- *
- * Echo a character on a terminal, if echoing is enabled.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The appropriate echo sequence for c gets added to the
- * terminal's output buffer.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- TdEcho(tPtr, c)
- register Terminal *tPtr; /* Terminal for which to echo. */
- register char c; /* Character to echo. */
- {
- if (!(tPtr->sgttyb.sg_flags & ECHO)) {
- return;
- }
- if (isprint(c)) {
- TdPutChar(tPtr, c);
- } else if (c == '\n') {
- if (tPtr->sgttyb.sg_flags & CRMOD) {
- TdPutChar(tPtr, '\r');
- }
- TdPutChar(tPtr, '\n');
- } else if (c == '\t') {
- TdPutChar(tPtr, c);
- } else if (c == 04) {
- /* Don't echo control-D's. */
- } else if (tPtr->localMode & LCTLECH) {
- TdPutChar(tPtr, '^');
- if (c == 0177) {
- TdPutChar(tPtr, '?');
- } else {
- TdPutChar(tPtr, c + 'A' - 1);
- }
- } else {
- TdPutChar(tPtr, c);
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdRetypeInput --
- *
- * This procedure is called to re-echo all of the characters in
- * the input buffer.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Characters get added to the terminal's output buffer.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- TdRetypeInput(tPtr, start)
- register Terminal *tPtr; /* Which terminal to re-echo for. */
- int start; /* Index within tPtr's buffer: start
- * echoing at the character AFTER this one. */
- {
- tPtr->keyIndex = start;
- tPtr->keyColumn = tPtr->column;
- while (start != tPtr->lastAddedIn) {
- NEXT(start, tPtr->inBufSize, start);
- TdEcho(tPtr, tPtr->inputBuffer[start]);
- }
- tPtr->lastHidden = -1;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdBackspace --
- *
- * Using mode information from tPtr, output the appropriate
- * sequence to backspace over the most recently typed character
- * in tPtr's input buffer. Also remove the character from
- * the input buffer.
- *
- * Results:
- * None.
- *
- * Side effects:
- * TPtr's input buffer ends up with less characters in it,
- * and stuff gets added to the output buffer.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- TdBackspace(tPtr)
- register Terminal *tPtr; /* Terminal to backspace. */
- {
- if (tPtr->sgttyb.sg_flags & ECHO) {
- if (tPtr->localMode & LCRTBS) {
- int count;
- char c;
-
- /*
- * CRT-style backspacing: the character can actually be erased.
- * Figure out how wide the character was, then back over it one
- * space at a time. If there's output intervening between us and
- * the next character to erase, then first re-echo everything.
- */
-
- if (tPtr->lastAddedIn == tPtr->lastHidden) {
- c = tPtr->ltchars.t_rprntc;
- if ((c & 0377) == 0377) {
- c = ltcharsDefault.t_rprntc;
- }
- TdEcho(tPtr, c);
- TdEcho(tPtr, '\n');
- TdRetypeInput(tPtr, tPtr->lastRemovedIn);
- tPtr->lastHidden = -1;
- }
- c = tPtr->inputBuffer[tPtr->lastAddedIn];
- if (isprint(c)) {
- count = 1;
- } else {
- int i, pos;
- char c2;
-
- /*
- * Anything besides a normal printing character is tricky. Tabs
- * are particularly nasty. To figure out how much to erase,
- * work forwards from a known position, computing the position
- * of the character just before the one being erased.
- */
-
- i = tPtr->keyIndex;
- pos = tPtr->keyColumn;
- while (TRUE) {
- NEXT(i, tPtr->inBufSize, i);
- if (i == tPtr->lastAddedIn) {
- break;
- }
- c2 = tPtr->inputBuffer[i];
- if (isprint(c2)) {
- pos++;
- } else if (c2 == '\t') {
- pos = (pos + 8) & ~07;
- } else if (((c2 == '\n') && !(tPtr->sgttyb.sg_flags & CRMOD))
- || (c2 == 04)) {
- /* No change to position. */
- } else if (tPtr->localMode & LCTLECH) {
- pos += 2;
- } else if (c2 == '\b') {
- pos -= 1;
- }
- }
- count = tPtr->column - pos;
- }
-
- for ( ; count > 0; count--) {
- if (tPtr->localMode & LCRTERA) {
- TdPutChar(tPtr, '\b');
- TdPutChar(tPtr, ' ');
- }
- TdPutChar(tPtr, '\b');
- }
- } else if (tPtr->localMode & LPRTERA) {
-
- /*
- * Hardcopy terminal: backspace by outputting erased characters
- * between "\" and "/" delimiters.
- */
-
- if (!(tPtr->flags & BS_IN_PROGRESS)) {
- TdPutChar(tPtr, '\\');
- tPtr->flags |= BS_IN_PROGRESS;
- }
- TdEcho(tPtr, tPtr->inputBuffer[tPtr->lastAddedIn]);
- } else {
-
- /*
- * Old-style backspace: just echo the backspace character.
- */
-
- TdEcho(tPtr, tPtr->sgttyb.sg_erase);
- }
- }
- PREV(tPtr->lastAddedIn, tPtr->inBufSize, tPtr->lastAddedIn);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdFlushInput --
- *
- * Empty the input buffer associated with a terminal.
- *
- * Results:
- * None.
- *
- * Side effects:
- * TPtr's input buffer is cleared.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- TdFlushInput(tPtr)
- register Terminal *tPtr; /* Terminal to flush. */
- {
- tPtr->lastAddedIn = tPtr->lastRemovedIn = 0;
- tPtr->lastBreak = tPtr->keyIndex = 0;
- tPtr->lastHidden = -1;
- tPtr->keyColumn = tPtr->column;
- tPtr->flags &= ~(LITERAL_NEXT|BS_IN_PROGRESS);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdFlushOutput --
- *
- * Empty the output queue for a terminal.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The output buffer for tPtr is emptied, and the terminal's raw
- * control procedure is invoked to empty any other buffers down
- * the line. The cooked side gets notified that the terminal
- * is now writable.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- TdFlushOutput(tPtr)
- register Terminal *tPtr; /* Terminal to flush. */
- {
- tPtr->lastAddedOut = tPtr->lastRemovedOut = 0;
- tPtr->outCharsBuffered = 0;
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_FLUSH_OUTPUT, 0,
- (char *) NULL, 0, (char *) NULL);
- (*tPtr->cookedProc)(tPtr->cookedData, TD_COOKED_WRITES_OK, 0,
- (char *) NULL, 0, (char *) NULL);
- }
- @
-
-
- 1.20.1.1
- log
- @Initial branch for Sprite server.
- @
- text
- @d21 1
- a21 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyDriver.c,v 1.20 92/03/18 16:33:08 rab Exp $ SPRITE (Berkeley)";
- @
-
-
- 1.19
- log
- @Use function prototypes. Lint.
- @
- text
- @d21 1
- a21 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyDriver.c,v 1.18 90/09/05 18:56:18 rab Exp Locker: kupfer $ SPRITE (Berkeley)";
- d1643 1
- a1643 1
- } else if (tPtr->tchars.t_intrc != -1) {
- @
-
-
- 1.18
- log
- @Add prototypes.
- @
- text
- @d21 1
- a21 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyDriver.c,v 1.17 90/06/27 11:16:52 shirriff Exp Locker: rab $ SPRITE (Berkeley)";
- d24 1
- d130 4
- a133 1
- int (*cookedProc)(); /* Procedure to call to register change
- d136 4
- a139 1
- int (*rawProc)(); /* Procedure to call to register change
- d206 13
- a218 10
- static void TdBackspace _ARGS_((register Terminal *tPtr));
- static void TdEcho _ARGS_((register Terminal *tPtr, register char c));
- static void TdFlushInput _ARGS_((register Terminal *tPtr));
- static void TdFlushOutput _ARGS_((register Terminal *tPtr));
- static void TdPutChar _ARGS_((register Terminal *tPtr, char c));
- static void TdRetypeInput _ARGS_((register Terminal *tPtr, int start));
- static int FormatInput _ARGS_((int command, Fmt_Format format, int inputSize,
- char *input, int *newInputSizePtr, char *newInput));
- static int FormatOutput _ARGS_((int command, Fmt_Format format, int outputSize,
- char *output, int *newOutputSizePtr, char *newOutput));
- d245 4
- a248 1
- int (*cookedProc)(); /* Procedure to call for control operations
- d253 4
- a256 1
- int (*rawProc)(); /* Procedure to call for control operations
- d672 1
- a672 1
- char *out;
- d691 1
- a691 1
- InBuf newInputBuf, newOutputBuf;
- d704 1
- a704 1
- &newSize, &newInputBuf) != FMT_OK) {
- d1083 1
- a1083 1
- char *input; /* Input buffer in client format */
- d1085 1
- a1085 1
- char *newInput; /* Out - Input buffer in our format */
- d1204 1
- a1204 1
- char *output; /* Output buffer in our format */
- d1206 1
- a1206 1
- char *newOutput; /* Out - Output buffer in the client's format */
- d1364 1
- a1364 1
- register char c;
- a1632 1
- Td_Signal signalInfo;
- @
-
-
- 1.17
- log
- @Added IOC_TTY_NOT_CONTROL_TTY.
- @
- text
- @d21 1
- a21 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyDriver.c,v 1.16 90/02/28 11:10:06 brent Exp $ SPRITE (Berkeley)";
- d199 11
- a209 8
- extern void TdBackspace();
- extern void TdEcho();
- extern void TdFlushInput();
- extern void TdFlushOutput();
- extern void TdPutChar();
- extern void TdRetypeInput();
- static int FormatInput();
- static int FormatOutput();
- d1660 1
- a1660 1
- void
- d1740 1
- a1740 1
- void
- d1788 1
- a1788 1
- void
- d1823 1
- a1823 1
- void
- d1831 1
- a1831 1
-
- d1838 1
- a1838 1
-
- d1855 1
- a1855 1
-
- d1862 1
- a1862 1
-
- d1886 1
- a1886 1
-
- d1895 1
- a1895 1
-
- d1900 1
- a1900 1
-
- d1907 1
- a1907 1
-
- d1934 1
- a1934 1
- void
- d1964 1
- a1964 1
- void
- @
-
-
- 1.16
- log
- @Added byteswapping for I/O controls.
- Fixed handling of IOC_TTY_FLUSH so it pays attention to the
- FREAD|FWRITE argument
- @
- text
- @d21 1
- a21 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyDriver.c,v 1.15 90/02/08 13:42:09 ouster Exp Locker: brent $ SPRITE (Berkeley)";
- d925 1
- d1082 1
- d1207 1
- @
-
-
- 1.15
- log
- @Generate SIGWINCH signal when window size changes.
- @
- text
- @d21 1
- a21 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyDriver.c,v 1.14 89/07/28 16:04:40 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
- d32 1
- d193 2
- d205 2
- d628 1
- a628 1
- Td_ControlCooked(terminal, command, inputSize, input, outputSizePtr,
- d632 2
- a633 1
- * (e.g. TIOCGETP). */
- d672 1
- d675 16
- d770 23
- a792 3
- case IOC_TTY_FLUSH:
- if (inputSize != 0) {
- goto invalid;
- a793 2
- TdFlushInput(tPtr);
- TdFlushOutput(tPtr);
- d795 1
- a795 1
-
- d952 7
- a958 4
-
- if (count < *outputSizePtr) {
- count = *outputSizePtr;
- }
- d960 11
- a970 1
- bcopy(out, output, count);
- a971 2
- *outputSizePtr = count;
- result = 0;
- d1030 3
- d1036 222
- @
-
-
- 1.14
- log
- @Implemented DECCTLQ (and its absence) correctly.
- @
- text
- @d21 1
- a21 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyDriver.c,v 1.13 89/07/19 08:58:37 ouster Exp $ SPRITE (Berkeley)";
- d894 2
- a895 1
- case IOC_TTY_SET_WINDOW_SIZE:
- d900 5
- d906 1
- @
-
-
- 1.13
- log
- @Various changes made to use in kernel: baud-rate changes, break
- characters, default owner of "anyone".
- @
- text
- @d21 1
- a21 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyDriver.c,v 1.12 89/06/03 16:46:20 ouster Exp $ SPRITE (Berkeley)";
- d1087 1
- d1105 6
- @
-
-
- 1.12
- log
- @Several changes: TD_HANGUP is now TD_GOT_CARRIER and TD_LOST_CARRIER,
- added TD_RAW_BAUD_RATE callback, changed TD_COOKED_SIGNAL to provide
- both signal number and controlling process group.
- @
- text
- @d21 1
- a21 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyDriver.c,v 1.11 89/04/20 10:24:35 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
- d239 1
- d248 1
- a248 1
- tPtr->owner = 0;
- d269 10
- d444 1
- a444 1
- if (pID != tPtr->owner) {
- d451 1
- a451 1
- } else if (familyID != tPtr->owner) {
- d921 1
- a921 1
- Td_BaudRate baud;
- d925 11
- a935 2
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_BAUD_RATE,
- sizeof(baud), (char *) &baud, 0, (char *) NULL);
- d1081 1
- d1107 3
- a1109 1
- * Skip line-editing and output-flushing stuff if in cbreak mode.
- a1122 1
- c &= 0177;
- d1316 25
- a1340 3
- /*
- * Not yet implemented...
- */
- @
-
-
- 1.11
- log
- @Flush buffer on signals. Also fixed WRITES_OK info to be consistent
- (some places did it when buffer empty, others when below threshold;
- this caused wakeups to get missed in some situations).
- @
- text
- @d21 1
- a21 1
- static char rcsid[] = "$Header: /a/newcmds/tty/RCS/ttyDriver.c,v 1.5 89/03/23 15:26:16 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
- d297 2
- d639 1
- a639 1
- Td_FlowChars flow;
- d657 11
- d711 1
- a711 1
- * buffer, and register change in flow control chars.
- a714 8
- if (in->sgttyb.sg_flags & RAW) {
- flow.stop = flow.start = -1;
- } else {
- flow.stop = tPtr->tchars.t_stopc;
- flow.start = tPtr->tchars.t_startc;
- }
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_FLOW_CHARS,
- sizeof(flow), (char *) &flow, 0, (char *) NULL);
- a817 8
- if (((tPtr->tchars.t_stopc != in->tchars.t_stopc)
- || (tPtr->tchars.t_startc != in->tchars.t_startc))
- && !(tPtr->sgttyb.sg_flags & RAW)) {
- flow.stop = tPtr->tchars.t_stopc;
- flow.start = tPtr->tchars.t_startc;
- (*tPtr->rawProc)(tPtr->rawData, TD_RAW_FLOW_CHARS,
- sizeof(flow), (char *) &flow, 0, (char *) NULL);
- }
- d904 29
- d1037 1
- a1037 1
- int next, sigNum, oldCharsBuffered;
- d1039 1
- d1173 1
- a1173 1
- sigNum = SIGINT;
- d1175 1
- d1177 2
- a1178 1
- sizeof(int), (char *) &sigNum, 0, (char *) NULL);
- d1181 1
- d1184 1
- a1184 1
- sigNum = SIGQUIT;
- d1187 1
- a1187 1
- sigNum = SIGTSTP;
- d1292 1
- a1292 2
- int operation; /* What just happened: TD_BREAK or
- * TD_HANGUP. */
- d1294 3
- @
-
-
- 1.10
- log
- @Massive upgrade to "new version" that is more modular and
- suitable for inclusion in kernel as well as user processes.
- Plus, there's flow control now and a whole bunch of other
- stuff.
- @
- text
- @d974 1
- a974 1
- if (tPtr->outCharsBuffered == 0) {
- a1147 1
- TdFlushInput(tPtr);
- d1150 2
- @
-
-
- 1.9
- log
- @Upgrade to use stuff in sys/ioctl.h instead of dev/tty.h.
- @
- text
- @d5 4
- a8 2
- * UNIX 4.2 BSD tty driver, using pseudo-devices for the application
- * interface and callback procedures for the device interface.
- d10 1
- a10 1
- * Copyright 1987 Regents of the University of California
- d21 1
- a21 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyDriver.c,v 1.8 89/01/19 12:36:13 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
- d24 2
- a26 1
- #include <sprite.h>
- a27 2
- #include <dev/pdev.h>
- #include <dev/tty.h>
- d29 1
- a29 2
- #include <list.h>
- #include <status.h>
- a30 2
- #include <string.h>
- #include <sys/file.h>
- d32 1
- a32 1
- #include <td.h>
- d35 1
- a35 1
- * The string below holds an error message if Td_Open fails.
- a37 25
- char td_ErrorMsg[150];
-
- /*
- * The structure below corresponds to an application's stream. There's
- * one of these for each open that involves a pseudo-device for which
- * this module is the server.
- */
-
- typedef struct ApplStream {
- List_Links links; /* Application streams are linked into a
- * list of all streams for the same
- * terminal. */
- struct Terminal *tPtr; /* Terminal with which this stream is
- * associated. */
- int streamID; /* Sprite identifier for request stream. */
- Address requestBuf; /* A buffer for requests and data from the
- * client */
- } ApplStream;
-
- /*
- * The structure below corresponds to one terminal (one call to Td_Open).
- * It maintains our state about the terminal, including stuff like the
- * input buffer and pointers to each of the open streams on the terminal.
- */
-
- a38 7
- int streamID; /* Sprite stream identifier for control
- * stream for pseudo-device. */
- List_Links applList; /* List of all application streams for this
- * terminal. */
- FILE *outputStream; /* Stream to use for outputting chars. to
- * terminal. */
-
- d41 1
- a41 1
- * same meanings as in 4.2 BSD; see the 4.2 BSD terminal driver
- d49 1
- d58 1
- a58 1
- Proc_PID owner; /* Identifier of controlling process or process
- d60 2
- d70 5
- a74 5
- int bufferSize; /* Number of bytes in inputBuffer. */
- int lastAdded; /* Index of last character added to buffer. */
- int lastRemoved; /* Index of last place from which character
- * was removed from buffer. If lastAdded =
- * lastRemoved, the buffer is empty. */
- d76 2
- a77 2
- * etc.) or lastRemoved if none in buffer. */
- int lastHidden; /* Value of lastAdded at the time the last
- d87 2
- a88 2
- * following two variables keep track of an index position in the
- * buffer, and column just to the right of where that character was
- d90 1
- a90 1
- * lastHidden or lastRemoved, and has two properties: a) it will
- d99 35
- a133 2
- struct Terminal *nextPtr; /* Next in list of all terminals, or NULL
- * for end-of-list. */
- d148 2
- d152 5
- a156 8
- #define EXCLUSIVE 1
- #define BS_IN_PROGRESS 2
- #define LITERAL_NEXT 4
- #define OWNER_FAMILY 8
-
- Terminal *firstTerminalPtr = NULL;
- /* First in list of all terminals being
- * being managed right now. */
- d172 3
- d182 1
- a182 1
- if ((dst) >= size) { \
- d189 1
- a189 1
- (dst) = size-1; \
- d193 26
- a218 78
- * The structure below describes the format of requests in the write
- * buffer of an ApplStream. The kernel queues up requests for us by
- * appending them to this buffer. In order to simplify the handling
- * of requests with a large amount of data, the kernel may break a
- * (write) request into smaller requests that each fit entirely in
- * the write buffer. The MAX_BYTES constant defines this upper limit
- * on the request data size. Also remember that writes are asynchronous
- * so this request buffer size limits the number of writes that can
- * be done before a context switch to the tty server process is required.
- */
-
- #define MAX_BYTES 2048
-
- typedef struct {
- Pdev_Request hdr;
- union {
- int i;
- char chars[MAX_BYTES];
- struct sgttyb sgttyb;
- struct tchars tchars;
- struct ltchars ltchars;
- Ioc_Owner owner;
- } data;
- } Request;
-
- /*
- * WRITE_BUF_SIZE The size of the buffer containing requests
- */
-
- #define REQUEST_BUF_SIZE sizeof(Request)
-
- /*
- * The structure below describes the format of reply messages returned
- * to the client.
- */
-
- typedef struct {
- Pdev_Reply hdr;
- union {
- int i;
- char chars[MAX_BYTES];
- struct sgttyb sgttyb;
- struct tchars tchars;
- struct ltchars ltchars;
- Ioc_Owner owner;
- } data;
- } Reply;
-
- /*
- * Forward references to procedures in this file:
- */
-
- static void TdApplRequest();
- static void TdBackspace();
- static void TdClose();
- static void TdControlRequest();
- static void TdEcho();
- static void TdFlushInput();
- static void TdFlushPdev();
- static void TdIoc();
- static void TdOpen();
- static void TdPutChar();
- static void TdRead();
- static int TdReady();
- static void TdReply();
- static void TdRetypeInput();
- static void TdSignal();
- static void TdWrite();
- static int TdSelectBits();
-
- /*
- *----------------------------------------------------------------------
- *
- * Td_Open --
- *
- * Arrange for filtering of characters between a pseudo-device
- * and a terminal device, emulating the UNIX 4.2 BSD "new"
- * terminal driver.
- a219 24
- * Results:
- * The return value is a token for the terminal, which may be
- * used in later calls to Td_ procedures. A NULL return value
- * means that the pseudo-device could not be opened. If realNamePtr
- * is non-NULL, *realNamePtr is filled in with a dynamically-
- * allocated string giving the actual name of the pseudo-device
- * file.
- *
- * Side effects:
- * A pseudo-device is opened in master mode. If realNamePtr is
- * NULL then name is the complete name of the pseudo device; if
- * realNamePtr is not NULL, then this procedure generates a
- * pseudo-device name of the form hostDir/nameXX, where "hostDir"
- * is the name of a standard host-specific directory for holding
- * terminal pseudo-devices and XX is an integer id appended to
- * "name" in order to find a device that isn't already in use.
- * Once this procedure returns, this module manages the pseudo
- * device to emulate the characteristics of a 4.2BSD terminal.
- * During calls to other procedures in this module, data will get
- * added to outputStream. Callbacks are set up using the Fs_Dispatch
- * facilities, so that this module gets notified when the pdev
- * channels have data ready. The caller must use the Fs_Dispatch
- * facilities.
- *
- d224 13
- a236 12
- Td_Open(name, outputStream, realNamePtr)
- char *name; /* Name of pseudo-device file to use for
- * application interface, or key for generating
- * name (if realNamePtr != NULL). If no
- * pseudo-device by that name exists, one
- * will be created. */
- FILE *outputStream; /* Where to write characters destined for
- * the device. */
- char **realNamePtr; /* If not NULL, then use "name" as a key for
- * a name (see above) and store actual name of
- * pseudo-device here. The memory for the
- * string is dynamically allocated. */
- a237 1
- int streamID;
- a238 59
- int pdevOpenFlags;
-
- /*
- * Pick a file name to use for the pseudo-device, if the caller didn't
- * give us one, then open the pseudo-device as the controlling process.
- */
-
- pdevOpenFlags = O_MASTER|O_RDWR|O_CREAT;
- if (realNamePtr != NULL) {
- char hostName[50];
- int i;
- char *actualName;
-
- if (gethostname(hostName, 20) != 0) {
- sprintf(td_ErrorMsg, "couldn't get host name (%s)",
- strerror(errno));
- return (Td_Terminal) NULL;
- } else {
- /*
- * Trim off domain name, if any
- */
- char *cp;
-
- cp = index(hostName, '.');
- if (cp != (char *)NULL) {
- *cp = '\0';
- }
- }
- actualName = (char *) malloc((unsigned) (12 + strlen(hostName)
- + strlen(name)));
- for (i = 1; i < 20; i++) {
- sprintf(actualName, "/hosts/%s/%s%d", hostName,
- name, i);
-
- /*
- * Because of umask, the file's mode may not actually get set
- * to 0666. Once the file is open, change the mode explicitly
- * to force it.
- */
-
- streamID = open(actualName, pdevOpenFlags, 0666);
- if (streamID >= 0) {
- fchmod(streamID, 0666);
- *realNamePtr = actualName;
- goto gotStream;
- }
- }
- free((char *) actualName);
- sprintf(td_ErrorMsg,
- "couldn't open a pseudo-device in \"/hosts/%s\"", hostName);
- return (Td_Terminal) NULL;
- } else {
- streamID = open(name, pdevOpenFlags, 0666);
- if (streamID < 0) {
- sprintf(td_ErrorMsg, "couldn't open \"%s\" (%s)",
- name, strerror(errno));
- return (Td_Terminal) NULL;
- }
- }
- a239 1
- gotStream:
- a240 8
- tPtr->streamID = streamID;
- List_Init(&tPtr->applList);
- tPtr->outputStream = outputStream;
-
- /*
- * Should set (or get?) device's baud rate here.
- */
-
- d245 1
- d250 3
- a252 3
- tPtr->bufferSize = 100;
- tPtr->lastAdded = 0;
- tPtr->lastRemoved = 0;
- d257 10
- a266 2
- tPtr->nextPtr = firstTerminalPtr;
- firstTerminalPtr = tPtr;
- a267 3
- Fs_EventHandlerCreate(streamID, FS_READABLE, TdControlRequest,
- (ClientData) tPtr);
-
- d274 1
- a274 1
- * Td_Close --
- d276 2
- a277 2
- * Close down a terminal pseudo-device and release all of the
- * state associated with it.
- d283 3
- a285 3
- * Memory gets recycled, and clients on the other end of the
- * pseudo-device will probably terminate. After this call,
- * the caller should never again use terminal.
- d291 3
- a293 3
- Td_Close(terminal)
- Td_Terminal terminal; /* Token identifying the terminal (the return
- * value from a previous Td_Open call). */
- d296 1
- a296 8
- register Terminal *tPtr2;
- register ApplStream *applPtr;
-
- while (!List_IsEmpty(&tPtr->applList)) {
- applPtr = (ApplStream *) List_First(&tPtr->applList);
- TdClose(tPtr, applPtr, FALSE);
- }
- close(tPtr->streamID);
- d298 1
- a298 10
- close(tPtr->streamID);
- if (firstTerminalPtr == tPtr) {
- firstTerminalPtr = tPtr->nextPtr;
- } else {
- for (tPtr2 = firstTerminalPtr; tPtr2->nextPtr != tPtr;
- tPtr2 = tPtr2->nextPtr) {
- /* Empty loop body. */
- }
- tPtr2->nextPtr = tPtr->nextPtr;
- }
- d305 5
- a309 1
- * Td_InputChar --
- d311 20
- a330 34
- * When one or more characters arrive from the "device" end of
- * a tty connection, the client calls this routine to pass in
- * the characters, one at a time. Td_InputChar handles echoing
- * and line editing, as appropriate, and .
- *
- * Results:
- * None.
- *
- * Side effects:
- * Characters may get output to the device, or passed on to
- * the application.
- *
- *----------------------------------------------------------------------
- */
-
- void
- Td_InputChar(terminal, c)
- Td_Terminal terminal; /* Token identifying the terminal from
- * which the characters came (the return
- * value from a previous Td_Open call). */
- register char c; /* Character to be input. */
- {
- register Terminal *tPtr = (Terminal *) terminal;
- int next;
-
- /*
- * See if we're supposed to re-echo all the characters in the
- * input buffer.
- */
-
- if (tPtr->localMode & LPENDIN) {
- tPtr->localMode &= ~LPENDIN;
- TdRetypeInput(tPtr, tPtr->lastBreak);
- }
- d332 2
- a333 156
- /*
- * Handle raw mode and literal characters specially.
- */
-
- if (tPtr->sgttyb.sg_flags & RAW) {
- goto addToBuffer;
- }
- if (tPtr->flags & LITERAL_NEXT) {
- tPtr->flags &= ~LITERAL_NEXT;
- goto addToBuffer;
- }
-
- /*
- * Handle line-editing characters such as erase and kill.
- */
-
- c &= 0177;
- if ((c == '\r') && (tPtr->sgttyb.sg_flags & CRMOD)) {
- c = '\n';
- }
- if (!(tPtr->sgttyb.sg_flags & CBREAK)) {
- if (c == tPtr->sgttyb.sg_erase) { /* Backspace. */
- if (tPtr->lastAdded != tPtr->lastBreak) {
- TdBackspace(tPtr);
- }
- return;
- } else if (c == tPtr->ltchars.t_werasc) { /* Delete word. */
- Boolean gotNonSpace = FALSE;
-
- while (tPtr->lastAdded != tPtr->lastBreak) {
- if (isspace(tPtr->inputBuffer[tPtr->lastAdded])) {
- if (gotNonSpace) {
- break;
- }
- } else {
- gotNonSpace = TRUE;
- }
- TdBackspace(tPtr);
- }
- return;
- } else if (c == tPtr->sgttyb.sg_kill) { /* Delete line. */
- if ((tPtr->lastHidden != -1) || !(tPtr->localMode & LCRTKIL)) {
- TdEcho(tPtr, c);
- TdEcho(tPtr, '\n');
- tPtr->lastAdded = tPtr->lastBreak;
- tPtr->lastHidden = -1;
- } else {
- while (tPtr->lastAdded != tPtr->lastBreak) {
- TdBackspace(tPtr);
- }
- }
- return;
- } else if (c == tPtr->ltchars.t_rprntc) { /* Re-echo all. */
- TdEcho(tPtr, c);
- TdEcho(tPtr, '\n');
- TdRetypeInput(tPtr, tPtr->lastRemoved);
- return;
- }
- }
-
- if (c == tPtr->ltchars.t_lnextc) {
- tPtr->flags |= LITERAL_NEXT;
- return;
- }
-
- /*
- * Generate signals in response to certain input characters. If this
- * isn't a signal character, then officially add it to the input
- * buffer.
- */
-
- if (c == tPtr->tchars.t_intrc) {
- TdSignal(tPtr, SIG_INTERRUPT);
- goto echo;
- } else if (c == tPtr->tchars.t_quitc) {
- TdSignal(tPtr, SIG_SUSPEND);
- goto echo;
- } else if (c == tPtr->ltchars.t_suspc) {
- TdSignal(tPtr, SIG_TTY_SUSPEND);
- goto echo;
- }
-
- /*
- * If the buffer is full, then reallocate it with a size twice as
- * large. Then add the character to the buffer.
- */
-
- addToBuffer:
- NEXT(tPtr->lastAdded, tPtr->bufferSize, next);
- if (next == tPtr->lastRemoved) {
- char *newBuffer;
- int src, dst;
-
- newBuffer = malloc((unsigned) 2*tPtr->bufferSize);
- for (src = tPtr->lastRemoved, dst = 0; src != tPtr->lastAdded; ) {
- NEXT(src, tPtr->bufferSize, src);
- dst += 1;
- newBuffer[dst] = tPtr->inputBuffer[src];
- }
- tPtr->lastBreak -= tPtr->lastRemoved;
- if (tPtr->lastBreak < 0) {
- tPtr->lastBreak += tPtr->bufferSize;
- }
- if (tPtr->lastHidden != -1) {
- tPtr->lastHidden -= tPtr->lastRemoved;
- if (tPtr->lastHidden < 0) {
- tPtr->lastHidden += tPtr->bufferSize;
- }
- }
- tPtr->inputBuffer = newBuffer;
- tPtr->bufferSize *= 2;
- tPtr->lastRemoved = 0;
- tPtr->lastAdded = dst;
- NEXT(dst, tPtr->bufferSize, next);
- }
- tPtr->inputBuffer[next] = c;
- tPtr->lastAdded = next;
-
- /*
- * Echo.
- */
-
- echo:
- if ((tPtr->sgttyb.sg_flags & ECHO) && !(tPtr->sgttyb.sg_flags & RAW)) {
- if (tPtr->flags & BS_IN_PROGRESS) {
- TdPutChar(tPtr, '/');
- tPtr->flags &= ~BS_IN_PROGRESS;
- }
- TdEcho(tPtr, c);
- }
-
- /*
- * Are there any characters that are ready for reading? If so,
- * set the kernel's select state to be readable.
- */
-
- if ((tPtr->sgttyb.sg_flags & (RAW|CBREAK)) || (c == tPtr->tchars.t_eofc) ||
- (c == tPtr->tchars.t_brkc) || (c == '\n')) {
- register ApplStream *applPtr;
- ReturnStatus status;
- int selectBits;
-
- tPtr->lastBreak = tPtr->lastAdded;
- tPtr->lastHidden = -1;
- tPtr->keyIndex = tPtr->lastAdded;
- tPtr->keyColumn = tPtr->column;
- selectBits = TdSelectBits(tPtr);
- LIST_FORALL(&tPtr->applList, (List_Links *) applPtr) {
- status = Fs_IOControl(applPtr->streamID, IOC_PDEV_READY,
- sizeof(int), (Address) &selectBits, 0,
- (Address) NULL);
- if (status != SUCCESS) {
- panic("Td_InputChar set select state: %s",
- Stat_GetMsg(status));
- }
- }
- d335 10
- d350 1
- a350 1
- * Td_GetState --
- d352 2
- a353 1
- * Return all of the state associated with the terminal.
- d356 1
- a356 2
- * The areas pointed to by the arguments get filled in with
- * the corresponding pieces of the terminal's state.
- d359 1
- a359 1
- * None.
- d365 3
- a367 6
- Td_GetState(terminal, basicPtr, charsPtr, localCharsPtr, localModePtr)
- Td_Terminal terminal; /* Token for terminal. */
- struct sgttyb *basicPtr; /* Where to store sgttyb stuff. */
- struct tchars *charsPtr; /* Where to store tchars stuff. */
- struct ltchars *localCharsPtr; /* Where to store ltchars stuff. */
- int *localModePtr; /* Where to store local mode word. */
- d370 5
- a374 4
- *basicPtr = tPtr->sgttyb;
- *charsPtr = tPtr->tchars;
- *localCharsPtr = tPtr->ltchars;
- *localModePtr = tPtr->localMode;
- d380 1
- a380 1
- * Td_SetState --
- d382 2
- a383 1
- * Change the internal state associated with a terminal.
- d385 39
- a423 9
- * Results:
- * None.
- *
- * Side effects:
- * The terminal's state gets set from the parameters. The
- * terminal's input buffer may also get flushed.
- *
- *----------------------------------------------------------------------
- */
- d425 4
- a428 142
- void
- Td_SetState(terminal, basicPtr, charsPtr, localCharsPtr, localMode, flush)
- Td_Terminal terminal; /* Token for terminal. */
- struct sgttyb *basicPtr; /* New sgttyb stuff. */
- struct tchars *charsPtr; /* New tchars. */
- struct ltchars *localCharsPtr; /* New ltchars. */
- int localMode; /* New local mode word. */
- Boolean flush; /* If TRUE, then flush input buffer. */
- {
- register Terminal *tPtr = (Terminal *) terminal;
-
- tPtr->sgttyb = *basicPtr;
- tPtr->tchars = *charsPtr;
- tPtr->ltchars = *localCharsPtr;
- tPtr->localMode = localMode;
- if (flush) {
- TdFlushInput(tPtr);
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdControlRequest --
- *
- * This procedure is invoked by Fs_Dispatcher when the control
- * stream for a pseudo-device is readable. This means that
- * a new stream is being opened on the pdev; TdControlRequest
- * handles this.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Add a new application stream to the pdev.
- *
- *----------------------------------------------------------------------
- */
-
- void
- TdControlRequest(tPtr)
- register Terminal *tPtr; /* Terminal whose control stream is ready. */
- {
- Pdev_Notify notify;
- register ApplStream *applPtr;
- int numBytes;
- Pdev_SetBufArgs setBuf;
- int true = 1;
-
- /*
- * Read the control stream for a message containing a new streamID.
- */
-
- numBytes = read(tPtr->streamID, (char *) ¬ify, sizeof(notify));
- if (numBytes != sizeof(notify)) {
- panic("%s; status \"%s\", count %d",
- "Td_Check couldn't read control stream",
- strerror(errno), numBytes);
- }
- if (notify.magic != PDEV_NOTIFY_MAGIC) {
- panic("%s: %d", "Td_Check got bad notify magic number",
- notify.magic);
- }
-
- /*
- * Set up the application state. This includes a request buffer used
- * by the kernel to pass client requests to us.
- */
-
- applPtr = (ApplStream *) malloc(sizeof(ApplStream));
- List_InitElement(&applPtr->links);
- List_Insert(&applPtr->links, LIST_ATFRONT(&tPtr->applList));
- applPtr->streamID = notify.newStreamID;
- applPtr->tPtr = tPtr;
- applPtr->requestBuf = (Address) malloc(REQUEST_BUF_SIZE);
- setBuf.requestBufAddr = applPtr->requestBuf;
- setBuf.requestBufSize = REQUEST_BUF_SIZE;
- setBuf.readBufAddr = NULL;
- setBuf.readBufSize = 0;
- Fs_IOControl(applPtr->streamID, IOC_PDEV_WRITE_BEHIND,
- sizeof(int), (Address)&true, 0, (Address) NULL);
- Fs_IOControl(applPtr->streamID, IOC_PDEV_SET_BUF,
- sizeof(Pdev_SetBufArgs), (Address)&setBuf,
- 0, (Address) NULL);
- Fs_EventHandlerCreate(notify.newStreamID, FS_READABLE, TdApplRequest,
- (ClientData) applPtr);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdApplRequest --
- *
- * This procedure is invoked by Fs_Dispatch when a request appears
- * for an application stream. This procedure reads the request and
- * dispatches to a routine to handle the request.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Characters may be output to devices or returned from a device's
- * internal buffer to an application.
- *
- *----------------------------------------------------------------------
- */
-
- void
- TdApplRequest(applPtr)
- register ApplStream *applPtr; /* Application stream that has a
- * request ready for processing. */
- {
- register Terminal *tPtr = applPtr->tPtr;
- Pdev_BufPtrs bufPtrs;
- Request *requestPtr;
- int numBytes;
-
- /*
- * Read the current pointers for the request buffer.
- */
-
- numBytes = read(applPtr->streamID, (char *) &bufPtrs,
- sizeof(Pdev_BufPtrs));
- if (numBytes != sizeof(Pdev_BufPtrs)) {
- panic("%s; status \"%s\", count %d",
- "Td_Check had trouble reading request buffer pointers",
- strerror(errno), numBytes);
- }
- if (bufPtrs.magic != PDEV_BUF_PTR_MAGIC) {
- panic("%s: %d", "Td_Check got bad pointer magic number",
- bufPtrs.magic);
- }
- /*
- * While there are still requests in the buffer, service them.
- */
- while (bufPtrs.requestFirstByte < bufPtrs.requestLastByte) {
- requestPtr =
- (Request *)&applPtr->requestBuf[bufPtrs.requestFirstByte];
- if (requestPtr->hdr.hdr.magic != PDEV_REQUEST_MAGIC) {
- panic("TdApplRequest, bad request magic # 0x%x\n",
- requestPtr->hdr.hdr.magic);
- }
- d430 7
- a436 20
- switch (requestPtr->hdr.hdr.operation) {
- case PDEV_OPEN:
- TdOpen(tPtr, applPtr, requestPtr);
- break;
- case PDEV_CLOSE:
- TdClose(tPtr, applPtr, TRUE);
- break;
- case PDEV_READ:
- TdRead(tPtr, applPtr, requestPtr);
- break;
- case PDEV_WRITE:
- case PDEV_WRITE_ASYNC:
- TdWrite(tPtr, applPtr, requestPtr);
- break;
- case PDEV_IOCTL:
- TdIoc(tPtr, applPtr, requestPtr);
- break;
- default:
- panic("Td_Check: bad request on request stream: %d",
- requestPtr->hdr.hdr.operation);
- d438 2
- a439 128
- /*
- * Tell the kernel we removed a request and see if there are any more.
- */
- bufPtrs.requestFirstByte += requestPtr->hdr.hdr.messageSize;
- Fs_IOControl(applPtr->streamID, IOC_PDEV_SET_PTRS,
- sizeof(Pdev_BufPtrs), (Address)&bufPtrs,
- 0, (Address) NULL);
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdOpen --
- *
- * This procedure is called when an PDEV_OPEN request is
- * received over an application stream.
- *
- * Results:
- * None.
- *
- * Side effects:
- * If the terminal is in exclusive mode then reject the open
- * and close down the application's stream. Otherwise, accept
- * it.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- TdOpen(tPtr, applPtr, reqPtr)
- Terminal *tPtr; /* Terminal for which a new stream was just
- * opened. */
- ApplStream *applPtr; /* Application's stream. */
- Request *reqPtr; /* Information about the open request. */
- {
- if (reqPtr->hdr.hdr.requestSize != 0) {
- panic("TdOpen got %d bytes of data with open or dup request",
- reqPtr->hdr.hdr.requestSize);
- }
- if (tPtr->flags & EXCLUSIVE) {
- TdReply(applPtr, (ReturnStatus) FS_FILE_BUSY, 0);
- TdClose(tPtr, applPtr, FALSE);
- } else {
- TdReply(applPtr, (ReturnStatus) SUCCESS, TdSelectBits(tPtr));
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdClose --
- *
- * This procedure is called to recycle all the information
- * associated with an application's stream.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The request stream gets closed, and our information about
- * the application stream gets freed up.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- TdClose(tPtr, applPtr, sendReply)
- register Terminal *tPtr; /* Terminal for which request was
- * received. */
- register ApplStream *applPtr; /* Application stream info. */
- Boolean sendReply; /* TRUE if we should reply to the
- * close request. This is done in
- * normal termination. FALSE means
- * no reply needed, used in error
- * recovery */
- {
- if (sendReply) {
- TdReply(applPtr, (ReturnStatus) SUCCESS, 0);
- }
- List_Remove(&applPtr->links);
- Fs_EventHandlerDestroy(applPtr->streamID);
- close(applPtr->streamID);
- free((char *) applPtr->requestBuf);
- free((char *) applPtr);
-
- if (List_IsEmpty(&tPtr->applList)) {
- tPtr->flags &= ~EXCLUSIVE;
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdRead --
- *
- * This procedure is called when an PDEV_READ request is
- * received over a request stream. Read ahead is not implemented
- * because we want to see each request so we can enforce ownership
- * so we see every client read request. Only the controlling
- * process (set via the IOC_OWNER IOControl) is allowed to read.
- * Other processes get signaled with SIG_TTY_INPUT.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Updates the lastRemoved and lastHidden pointers into the terminal's
- * input buffer. The available data is moved to the pseudo-device
- * read buffer and the kernel is poked.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- TdRead(tPtr, applPtr, reqPtr)
- register Terminal *tPtr; /* Terminal for which request was received. */
- ApplStream *applPtr; /* Application stream info. */
- Request *reqPtr; /* Information about the request. */
- {
- Reply reply;
- register Reply *replyPtr;
- int src, count;
- ReturnStatus status;
-
- if (reqPtr->hdr.hdr.requestSize != 0) {
- panic("TdRead got %d requestSize for read operation",
- reqPtr->hdr.hdr.requestSize);
- d447 3
- d451 5
- a455 14
- TdRetypeInput(tPtr, tPtr->lastBreak);
- }
-
- /*
- * See if this application is in the right process group. If not,
- * then signal it and don't give it any input.
- */
-
- if (tPtr->flags & OWNER_FAMILY) {
- if (reqPtr->hdr.param.read.familyID != tPtr->owner) {
- notOwner:
- Sig_Send(SIG_TTY_INPUT, reqPtr->hdr.param.read.procID, FALSE);
- TdReply(applPtr, (ReturnStatus) FS_WOULD_BLOCK, FS_WRITABLE);
- return;
- a456 2
- } else if (reqPtr->hdr.param.read.procID != tPtr->owner) {
- goto notOwner;
- d464 4
- a467 3
- if (tPtr->lastBreak == tPtr->lastRemoved) {
- TdReply(applPtr, (ReturnStatus) FS_WOULD_BLOCK, FS_WRITABLE);
- return;
- d469 17
- a485 13
-
- /*
- * Count how many bytes should be returned to the user, and
- * update the terminal's input buffer pointer.
- */
- reply.hdr.replySize = 0;
- src = tPtr->lastRemoved;
- while (tPtr->lastRemoved != tPtr->lastBreak) {
- NEXT(tPtr->lastRemoved, tPtr->bufferSize, tPtr->lastRemoved);
- if (tPtr->lastRemoved == tPtr->lastHidden) {
- tPtr->lastHidden = -1;
- }
- reply.hdr.replySize++;
- a486 1
- register char c = tPtr->inputBuffer[tPtr->lastRemoved];
- d488 1
- a488 1
- reply.hdr.replySize--; /* Don't return end-of-file chars. */
- a493 3
- if (reply.hdr.replySize >= reqPtr->hdr.hdr.replySize) {
- break;
- }
- d495 2
- d498 3
- a500 7
- if (reply.hdr.replySize > MAX_BYTES) {
- /*
- * Have to dynamically allocate a large enough reply.
- */
- replyPtr = (Reply *) malloc((unsigned) (sizeof(Pdev_Reply)
- + reply.hdr.replySize));
- replyPtr->hdr = reply.hdr;
- d502 1
- a502 1
- replyPtr = &reply;
- d504 21
- a524 36
-
- /*
- * Copy the data into the reply and give it to the kernel.
- */
-
- replyPtr->hdr.magic = PDEV_REPLY_MAGIC;
- replyPtr->hdr.status = SUCCESS;
- replyPtr->hdr.selectBits = TdSelectBits(tPtr);
- for (count = 0 ; count < reply.hdr.replySize ; count++) {
- NEXT(src, tPtr->bufferSize, src);
- replyPtr->data.chars[count] = tPtr->inputBuffer[src];
- }
- replyPtr->hdr.replyBuf = &replyPtr->data.chars[0];
- status = Fs_IOControl(applPtr->streamID, IOC_PDEV_REPLY,
- sizeof(Pdev_Reply),
- (Address) replyPtr, 0, (Address) NULL);
- if (status != SUCCESS) {
- panic("%s; status \"%s\"", "Td_Read couldn't send reply",
- Stat_GetMsg(status));
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdWrite --
- *
- * This procedure is called when an PDEV_WRITE request is
- * received over a request stream.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Perform output processing on the characters, if enabled, and
- * pass the characters on to the device.
- d530 14
- a543 6
- static void
- TdWrite(tPtr, applPtr, reqPtr)
- Terminal *tPtr; /* Terminal for which request was
- * received. */
- ApplStream *applPtr; /* Application stream info. */
- register Request *reqPtr; /* Information about the request. */
- d545 1
- a545 1
- register char *p;
- d547 1
- d549 1
- a549 5
- /*
- * Handle the write request in a loop, processing all the characters
- * in the request data buffer, then refilling the buffer, until there
- * are no more characters left.
- */
- d551 3
- a553 3
- for (p = reqPtr->data.chars; reqPtr->hdr.hdr.requestSize > 0;
- p++, reqPtr->hdr.hdr.requestSize--) {
- c = *p;
- d555 1
- a555 1
- putc(c, tPtr->outputStream);
- d568 1
- a568 1
-
- d570 12
- a581 3
- tPtr->keyIndex = tPtr->lastAdded;
- if (tPtr->lastAdded != tPtr->lastRemoved) {
- tPtr->lastHidden = tPtr->lastAdded;
- d583 60
- d644 10
- a653 33
- /*
- * Don't need to reply explicitly because the write has already
- * been handled for the client by the kernel.
- */
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdIoc --
- *
- * This procedure is called when an PDEV_IOCONTROL request is
- * received over a request stream.
- *
- * Results:
- * None.
- *
- * Side effects
- * Read the IOControl input data, if any, process the request,
- * and send a response back. The exact actions taken depend on
- * the IOControl operation.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- TdIoc(tPtr, applPtr, reqPtr)
- register Terminal *tPtr; /* Terminal for which request was received. */
- ApplStream *applPtr; /* Application stream info. */
- Request *reqPtr; /* Information about the request. */
- {
- Reply reply;
- ReturnStatus status;
- d655 3
- a657 2
- reply.hdr.replySize = 0;
- switch (reqPtr->hdr.param.ioctl.command) {
- d660 2
- a661 2
- if ((reqPtr->hdr.hdr.requestSize != sizeof(int))
- || (reqPtr->data.i != NTTYDISC)) {
- d667 1
- a667 1
- if (reqPtr->hdr.hdr.requestSize != 0) {
- d670 3
- a672 2
- reply.data.i = NTTYDISC;
- reply.hdr.replySize = sizeof(int);
- d676 1
- a676 1
- if (reqPtr->hdr.hdr.requestSize != 0) {
- d679 2
- a680 2
- reply.data.sgttyb = tPtr->sgttyb;
- reply.hdr.replySize = sizeof(struct sgttyb);
- d684 6
- d692 1
- a692 1
- if (reqPtr->hdr.hdr.requestSize != sizeof(struct sgttyb)) {
- d695 6
- a700 1
- if ((tPtr->sgttyb.sg_flags ^ reqPtr->data.sgttyb.sg_flags) & RAW) {
- d702 8
- d711 1
- a711 1
- tPtr->sgttyb = reqPtr->data.sgttyb;
- d715 1
- a715 1
- if (reqPtr->hdr.hdr.requestSize != 0) {
- d722 1
- a722 1
- if (reqPtr->hdr.hdr.requestSize != 0) {
- d732 1
- a732 1
- if (reqPtr->hdr.hdr.requestSize != 0) {
- d736 1
- d740 1
- a740 1
- if (reqPtr->hdr.hdr.requestSize != 1) {
- d743 1
- a743 1
- Td_InputChar((Td_Terminal) tPtr, reqPtr->data.chars[0]);
- d745 20
- a764 6
-
- case IOC_TTY_SET_BREAK: /* Not implemented. */
- goto invalid;
-
- case IOC_TTY_CLEAR_BREAK: /* Not implemented. */
- goto invalid;
- a765 6
- case IOC_TTY_SET_DTR: /* Not implemented. */
- goto invalid;
-
- case IOC_TTY_CLEAR_DTR: /* Not implemented. */
- goto invalid;
-
- d767 1
- a767 1
- if (reqPtr->hdr.hdr.requestSize != 0) {
- d770 1
- a770 1
- reply.data.owner.id = tPtr->owner;
- d772 1
- a772 1
- reply.data.owner.procOrFamily = IOC_OWNER_FAMILY;
- d774 1
- a774 1
- reply.data.owner.procOrFamily = IOC_OWNER_PROC;
- d776 2
- a777 1
- reply.hdr.replySize = sizeof(Ioc_Owner);
- d781 1
- a781 1
- if (reqPtr->hdr.hdr.requestSize != sizeof(Ioc_Owner)) {
- d784 2
- a785 2
- tPtr->owner = reqPtr->data.owner.id;
- if (reqPtr->data.owner.procOrFamily == IOC_OWNER_FAMILY) {
- d793 3
- a795 11
- /*
- * We ignore the request, but the kernel sticks in the offset
- * and makes the argument be an integer. So, if this check
- * is actually needed, it should at least get the check right!
- */
- if (reqPtr->hdr.hdr.requestSize != sizeof(int)) {
- goto invalid;
- }
- reply.data.i = tPtr->lastBreak - tPtr->lastRemoved;
- if (reply.data.i < 0) {
- reply.data.i += tPtr->bufferSize;
- d797 2
- a798 1
- reply.hdr.replySize = sizeof(int);
- d802 1
- a802 1
- if (reqPtr->hdr.hdr.requestSize != 0) {
- d805 2
- a806 2
- reply.data.tchars = tPtr->tchars;
- reply.hdr.replySize = sizeof(struct tchars);
- d810 1
- a810 1
- if (reqPtr->hdr.hdr.requestSize != sizeof(struct tchars)) {
- d813 9
- a821 1
- tPtr->tchars = reqPtr->data.tchars;
- d825 1
- a825 1
- if (reqPtr->hdr.hdr.requestSize != sizeof(int)) {
- d828 1
- a828 1
- tPtr->localMode |= reqPtr->data.i;
- d832 1
- a832 1
- if (reqPtr->hdr.hdr.requestSize != sizeof(int)) {
- d835 1
- a835 1
- tPtr->localMode &= ~reqPtr->data.i;
- d839 1
- a839 1
- if (reqPtr->hdr.hdr.requestSize != sizeof(int)) {
- d842 1
- a842 1
- tPtr->localMode = reqPtr->data.i;
- d846 1
- a846 1
- if (reqPtr->hdr.hdr.requestSize != 0) {
- d849 2
- a850 2
- reply.data.i = tPtr->localMode;
- reply.hdr.replySize = sizeof(int);
- d854 1
- a854 1
- if (reqPtr->hdr.hdr.requestSize != sizeof(struct ltchars)) {
- d857 1
- a857 1
- tPtr->ltchars = reqPtr->data.ltchars;
- d861 1
- a861 1
- if (reqPtr->hdr.hdr.requestSize != 0) {
- d864 2
- a865 2
- reply.data.ltchars = tPtr->ltchars;
- reply.hdr.replySize = sizeof(struct ltchars);
- d869 3
- a871 2
- reply.hdr.replySize = sizeof(int);
- reply.data.i = 0;
- d877 16
- a892 1
-
- d897 313
- d1211 3
- a1213 2
- * Send the reply back to the application. We pass a reply to the
- * kernel which includes a size and an address for any reply data.
- d1216 8
- a1223 13
- reply.hdr.magic = PDEV_REPLY_MAGIC;
- reply.hdr.status = SUCCESS;
- if (reply.hdr.replySize != reqPtr->hdr.hdr.replySize) {
- goto invalid;
- }
- reply.hdr.selectBits = TdSelectBits(tPtr);
- reply.hdr.replyBuf = &reply.data.chars[0];
- status = Fs_IOControl(applPtr->streamID, IOC_PDEV_REPLY,
- sizeof(Pdev_Reply), (Address) &reply,
- 0, (Address) NULL);
- if (status != SUCCESS) {
- panic("%s; status \"%s\"", "Td_Ioc couldn't send reply",
- Stat_GetMsg(status));
- d1225 5
- a1229 1
- return;
- d1231 5
- a1235 2
- invalid:
- TdReply(applPtr, (ReturnStatus) FS_INVALID_ARG, TdSelectBits(tPtr));
- d1241 1
- a1241 1
- * TdReply --
- d1243 3
- a1245 2
- * Send a reply back with no data; just a return status. This
- * procedure is most often used for error returns.
- d1251 2
- a1252 2
- * The application will receive status as the return from the
- * system call it invoked.
- d1257 6
- a1262 5
- static void
- TdReply(applPtr, status, selectBits)
- ApplStream *applPtr; /* Application stream info. */
- ReturnStatus status; /* Error code to send to application. */
- int selectBits; /* Current select state for the stream */
- a1263 13
- Pdev_Reply reply;
-
- reply.magic = PDEV_REPLY_MAGIC;
- reply.selectBits = selectBits;
- reply.status = status;
- reply.replySize = 0;
- reply.replyBuf = NULL;
- status = Fs_IOControl(applPtr->streamID, IOC_PDEV_REPLY,
- sizeof(Pdev_Reply), (Address) &reply, 0, (Address) NULL);
- if (status != SUCCESS) {
- panic("%s; status \"%s\"", "Td_Reply couldn't send reply",
- Stat_GetMsg(status));
- }
- d1269 1
- a1269 1
- * TdSelectBits --
- d1271 4
- a1274 4
- * Return the current select state of the tty stream. This
- * examines the mode of the tty and decides if there are any
- * characters available for reading. The stream is always
- * writable, but never exceptable.
- a1275 3
- * Note, this doesn't pay any attention to terminal ownership,
- * although it could.
- *
- d1277 1
- a1277 2
- * An or'd combination of FS_READABLE and FS_WRITABLE that
- * indicate the current select state.
- d1280 2
- a1281 1
- * None.
- d1286 4
- a1289 3
- static int
- TdSelectBits(tPtr)
- register Terminal *tPtr;
- d1291 40
- a1330 1
- register int selectBits = FS_WRITABLE;
- d1332 11
- a1342 2
- if (tPtr->lastBreak != tPtr->lastRemoved) {
- selectBits |= FS_READABLE;
- d1344 3
- a1346 1
- return(selectBits);
- d1360 2
- a1361 2
- * The appropriate echo sequence for c get written to the
- * terminal's output stream.
- d1400 1
- a1400 1
- * TdPutChar --
- d1402 2
- a1403 4
- * Output a character to the device associated with a terminal,
- * and keep track of the current column while outputting the
- * character. This routine also substitutes spaces for tabs,
- * if that's the mode the terminal is in.
- d1409 1
- a1409 2
- * TPtr->column gets updated and stuff gets added to the device's
- * output stream.
- d1415 4
- a1418 3
- TdPutChar(tPtr, c)
- register Terminal *tPtr; /* Terminal on which to output. */
- char c; /* Character to output. */
- d1420 5
- a1424 18
- register FILE *stream = tPtr->outputStream;
-
- if (isprint(c)) {
- tPtr->column += 1;
- } else if (c == '\r') {
- tPtr->column = 0;
- } else if (c == '\t') {
- int count = 8 - (tPtr->column & 07);
-
- tPtr->column += count;
- if ((tPtr->sgttyb.sg_flags & TBDELAY) == XTABS) {
- for ( ; count > 0; count--) {
- putc(' ', stream);
- }
- return;
- }
- } else if (c == '\b') {
- tPtr->column -= 1;
- d1426 1
- a1426 1
- putc(c, stream);
- d1436 2
- a1437 1
- * in tPtr's buffer. Also remove the character from the buffer.
- d1443 2
- a1444 2
- * TPtr's buffer ends up with one less character in it. Stuff
- * gets output on tPtr's outputStream.
- d1465 1
- a1465 1
- if (tPtr->lastAdded == tPtr->lastHidden) {
- d1467 1
- a1467 1
- if (c == -1) {
- d1472 1
- a1472 1
- TdRetypeInput(tPtr, tPtr->lastRemoved);
- d1475 1
- a1475 1
- c = tPtr->inputBuffer[tPtr->lastAdded];
- d1492 2
- a1493 2
- NEXT(i, tPtr->bufferSize, i);
- if (i == tPtr->lastAdded) {
- d1524 1
- a1524 1
- * between "\" and "/" delimeters.
- d1531 1
- a1531 1
- TdEcho(tPtr, tPtr->inputBuffer[tPtr->lastAdded]);
- d1537 1
- a1537 1
-
- d1541 1
- a1541 1
- PREV(tPtr->lastAdded, tPtr->bufferSize, tPtr->lastAdded);
- d1547 1
- a1547 1
- * TdSignal --
- d1549 1
- a1549 2
- * Generate a signal for the process group associated with a
- * terminal.
- d1555 1
- a1555 2
- * Processes get signalled (unless there's no process group for
- * the terminal). The terminal's buffer gets flushed.
- d1561 2
- a1562 3
- TdSignal(tPtr, signal)
- register Terminal *tPtr; /* Terminal for which to signal. */
- int signal; /* Number of signal to generate. */
- d1564 3
- a1566 30
- TdFlushInput(tPtr);
- if (tPtr->owner != 0) {
- Sig_Send(signal, tPtr->owner, tPtr->flags & OWNER_FAMILY);
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TdRetypeInput --
- *
- * This procedure is called to re-echo all of the characters in
- * the input buffer.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Characters get written to the terminal device.
- *
- *----------------------------------------------------------------------
- */
-
- void
- TdRetypeInput(tPtr, start)
- register Terminal *tPtr; /* Which terminal to re-echo for. */
- int start; /* Index within tPtr's buffer: start
- * echoing at the character AFTER this one. */
- {
- tPtr->keyIndex = tPtr->lastRemoved;
- d1568 1
- a1568 5
- while (start != tPtr->lastAdded) {
- NEXT(start, tPtr->bufferSize, start);
- TdEcho(tPtr, tPtr->inputBuffer[start]);
- }
- tPtr->lastHidden = -1;
- d1574 1
- a1574 1
- * TdFlushInput --
- d1576 1
- a1576 1
- * Empty the input buffer associated with a terminal.
- d1582 4
- a1585 1
- * TPtr's input buffer is flushed.
- d1591 1
- a1591 1
- TdFlushInput(tPtr)
- d1594 6
- a1599 5
- tPtr->lastAdded = tPtr->lastRemoved = 0;
- tPtr->lastBreak = tPtr->keyIndex = 0;
- tPtr->lastHidden = -1;
- tPtr->keyColumn = tPtr->column;
- tPtr->flags &= ~(LITERAL_NEXT|BS_IN_PROGRESS);
- @
-
-
- 1.8
- log
- @Make PDEV_WRITE_ASYNC equivalent to PDEV_WRITE.
- @
- text
- @d19 1
- a19 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/ttyDriver.c,v 1.7 89/01/16 10:39:54 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
- d33 1
- d241 17
- a257 17
- extern void TdApplRequest();
- extern void TdBackspace();
- extern void TdClose();
- extern void TdControlRequest();
- extern void TdEcho();
- extern void TdFlushInput();
- extern void TdFlushPdev();
- extern void TdIoc();
- extern void TdOpen();
- extern void TdPutChar();
- extern void TdRead();
- extern int TdReady();
- extern void TdReply();
- extern void TdRetypeInput();
- extern void TdSignal();
- extern void TdWrite();
- extern int TdSelectBits();
- d671 3
- a673 3
- Tty_BasicParams *basicPtr; /* Where to store sgttyb stuff. */
- Tty_Chars *charsPtr; /* Where to store tchars stuff. */
- Tty_LocalChars *localCharsPtr; /* Where to store ltchars stuff. */
- d703 3
- a705 3
- Tty_BasicParams *basicPtr; /* New sgttyb stuff. */
- Tty_Chars *charsPtr; /* New tchars. */
- Tty_LocalChars *localCharsPtr; /* New ltchars. */
- @
-
-
- 1.7
- log
- @Changed handling of hidden characters to make it more like UNIX.
- @
- text
- @d19 1
- a19 1
- static char rcsid[] = "$Header: ttyDriver.c,v 1.6 88/10/14 13:09:19 brent Exp $ SPRITE (Berkeley)";
- d853 1
- @
-
-
- 1.6
- log
- @Updated to new Pdev_Request declaration
- @
- text
- @d19 1
- a19 1
- static char rcsid[] = "$Header: ttyDriver.c,v 1.5 88/10/07 19:00:59 douglis Exp $ SPRITE (Berkeley)";
- d111 3
- a113 3
- * them. -1 means none of the characters in
- * the buffer arrived before the last output
- * to the terminal. */
- d532 1
- a532 1
- if (!(tPtr->localMode & LCRTKIL)) {
- d536 1
- d634 1
- d1602 6
- d1609 1
- @
-
-
- 1.5
- log
- @fixed bad check for size of arg to ioctl.
- @
- text
- @d19 1
- a19 1
- static char rcsid[] = "$Header: ttyDriver.c,v 1.4 88/09/28 10:06:32 brent Exp $ SPRITE (Berkeley)";
- a27 1
- #include <fs.h>
- d835 1
- a835 1
- if (requestPtr->hdr.magic != PDEV_REQUEST_MAGIC) {
- d837 1
- a837 1
- requestPtr->hdr.magic);
- d840 1
- a840 1
- switch (requestPtr->hdr.operation) {
- d858 1
- a858 1
- requestPtr->hdr.operation);
- d863 1
- a863 1
- bufPtrs.requestFirstByte += requestPtr->hdr.messageSize;
- d896 1
- a896 1
- if (reqPtr->hdr.requestSize != 0) {
- d898 1
- a898 1
- reqPtr->hdr.requestSize);
- d985 1
- a985 1
- if (reqPtr->hdr.requestSize != 0) {
- d987 1
- a987 1
- reqPtr->hdr.requestSize);
- d1046 1
- a1046 1
- if (reply.hdr.replySize >= reqPtr->hdr.replySize) {
- d1118 2
- a1119 2
- for (p = reqPtr->data.chars; reqPtr->hdr.requestSize > 0;
- p++, reqPtr->hdr.requestSize--) {
- d1180 1
- a1180 1
- if ((reqPtr->hdr.requestSize != sizeof(int))
- d1187 1
- a1187 1
- if (reqPtr->hdr.requestSize != 0) {
- d1195 1
- a1195 1
- if (reqPtr->hdr.requestSize != 0) {
- d1205 1
- a1205 1
- if (reqPtr->hdr.requestSize != sizeof(struct sgttyb)) {
- d1215 1
- a1215 1
- if (reqPtr->hdr.requestSize != 0) {
- d1222 1
- a1222 1
- if (reqPtr->hdr.requestSize != 0) {
- d1232 1
- a1232 1
- if (reqPtr->hdr.requestSize != 0) {
- d1239 1
- a1239 1
- if (reqPtr->hdr.requestSize != 1) {
- d1258 1
- a1258 1
- if (reqPtr->hdr.requestSize != 0) {
- d1271 1
- a1271 1
- if (reqPtr->hdr.requestSize != sizeof(Ioc_Owner)) {
- d1288 1
- a1288 1
- if (reqPtr->hdr.requestSize != sizeof(int)) {
- d1299 1
- a1299 1
- if (reqPtr->hdr.requestSize != 0) {
- d1307 1
- a1307 1
- if (reqPtr->hdr.requestSize != sizeof(struct tchars)) {
- d1314 1
- a1314 1
- if (reqPtr->hdr.requestSize != sizeof(int)) {
- d1321 1
- a1321 1
- if (reqPtr->hdr.requestSize != sizeof(int)) {
- d1328 1
- a1328 1
- if (reqPtr->hdr.requestSize != sizeof(int)) {
- d1335 1
- a1335 1
- if (reqPtr->hdr.requestSize != 0) {
- d1343 1
- a1343 1
- if (reqPtr->hdr.requestSize != sizeof(struct ltchars)) {
- d1350 1
- a1350 1
- if (reqPtr->hdr.requestSize != 0) {
- d1377 1
- a1377 1
- if (reply.hdr.replySize != reqPtr->hdr.replySize) {
- @
-
-
- 1.4
- log
- @Updated to latest typedefs
- @
- text
- @d19 1
- a19 1
- static char rcsid[] = "$Header: ttyDriver.c,v 1.3 88/07/28 17:47:40 ouster Exp $ SPRITE (Berkeley)";
- d1284 6
- a1289 1
- if (reqPtr->hdr.requestSize != 0) {
- @
-
-
- 1.3
- log
- @Lint.
- @
- text
- @d19 1
- a19 1
- static char rcsid[] = "$Header: ttyDriver.c,v 1.2 88/07/25 13:27:45 ouster Exp $ SPRITE (Berkeley)";
- d203 1
- a203 1
- Pdev_NewRequest hdr;
- d226 1
- a226 1
- Pdev_NewReply hdr;
- d1056 1
- a1056 1
- replyPtr = (Reply *) malloc((unsigned) (sizeof(Pdev_NewReply)
- d1076 1
- a1076 1
- sizeof(Pdev_NewReply),
- d1379 1
- a1379 1
- sizeof(Pdev_NewReply), (Address) &reply,
- d1415 1
- a1415 1
- Pdev_NewReply reply;
- d1423 1
- a1423 1
- sizeof(Pdev_NewReply), (Address) &reply, 0, (Address) NULL);
- @
-
-
- 1.2
- log
- @Lint.
- @
- text
- @d19 1
- a19 1
- static char rcsid[] = "$Header: ttyDriver.c,v 1.1 88/07/01 09:40:52 ouster Exp $ SPRITE (Berkeley)";
- d778 1
- a778 1
- sizeof(int), (Address)&true, 0, NULL);
- d780 2
- a781 1
- sizeof(Pdev_SetBufArgs), (Address)&setBuf, 0, NULL);
- d783 1
- a783 1
- (Address) applPtr);
- d867 1
- a867 1
- 0, NULL);
- d1077 1
- a1077 1
- (Address) replyPtr, 0, NULL);
- d1102 1
- d1379 2
- a1380 1
- sizeof(Pdev_NewReply), (Address) &reply, 0, NULL);
- d1423 1
- a1423 1
- sizeof(Pdev_NewReply), (Address) &reply, 0, NULL);
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @d19 1
- a19 1
- static char rcsid[] = "$Header: ttyDriver.c,v 2.9 88/05/24 17:13:38 deboor Exp $ SPRITE (Berkeley)";
- a311 1
- ReturnStatus status;
- a811 1
- ReturnStatus status;
- @
-